一. 引用变量
- PHP引用变量的概念及定义方式
概念
在PHP中引用意味着用不同的名字访问同一个变量内容。
定义方式
使用&符号
- unset只会取消引用,不会销毁空间
$a = 1;
$b = &$a;
unset($b);
echo $a;
- 对象本身就是引用传值
$data = ['a','b','c'];
foreach($data as $key=>$val){
$val = &$data[$key];
}
程序运行时,每一次循环结束后变量$data的值是什么?
程序执行完成后,变量$data的值是什么?
核心:函数体中,$val引用$data[$i],因此,只要进行下一次遍历,函数体代码会影响$val的值
二. 常量及数据类型考点
- PHP中字符串可以使用哪三种定义方式?各自的区别?
方式一:单引号
方式二:双引号
方式三:heredoc和newdoc
区别:
单引号不能解析变量
单引号不能解析转义字符,只能解析单引号和反斜线本身
变量和变量、变量和字符串、字符串与字符串之间可以用.连接
双引号可以解析变量,变量可以使用特殊字符串和{}包含
双引号可以解析所有转义字符
也可以用.来连接
单引号效率高于双引号
heredoc类似于单引号
newdoc类似于双引号
用于处理大文本
$str = <<<EOT
EOT;
三. 数据类型
三大数据类型(标量、复合、特殊)
- 浮点类型
不能用于比较运算中
$a = 0.1;
$b = 0.7;
if($a+$b == 0.8) ===>false
需要转成二进制会有损耗
- 布尔类型
false的七种情况
0, 0.0 , ‘’,‘0’,false, array(),null - 数组类型
超全局数组
$GLOBALS $_GET $_POST $_REQUEST $_SESSION $_COOKIE $_SERVER $_FILES $ENV
$_SERVER['SERVER_ADDR'] 服务器的IP
$_SERVER['SERVER_NAME'] 服务器名称
$_SERVER['REQUEST_TIME'] 请求时间
$_SERVER['QUERY_STRING'] 请求参数,?后的部分
$_SERVER['HTTP_REFERER'] 上一级请求
$_SERVER['HTTP_USER_AGENT'] 浏览器信息
$_SERVER['REMOTE_ADDR'] 客户端IP
$_SERVER['REQUEST_URI'] 请求的地址
$_SERVER['PATH_INFO'] 用于处理路由
http://www.itxdl.cn/index.php/user/reg?status=1
user/reg 属于PATH_INFO
status=1 属于query_string
- NULL
三种情况
直接赋值为NULL、未定义的变量、unset销毁的变量
四. 常量
- 定义
const、define
const更快,是语言结构,define是函数
define不能用于类常量定义,const可以
常量一经定义,不能修改,不能删除 - 预定义常量
__FILE__ __LINE__ __DIR__ __FUNCTION__ __CLASS_ __TRAIT__ __METHOD__ __NAMESPACE__
面试真题
Q:用PHP写出显示客户端IP和服务器IP的代码
$_SERVER['REMOTE_ADDR']
$_SERVER['SERVER_ADDR']
Q:__FILE__什么意思?
__FILE__ 返回所在文件的路径和文件名
五. 运算符考点
面试真题
foo()和@foo()之间的区别
@是错误控制符,当将其放在表达式之前,该表达式可能产生的任何错误信息都被忽略
- 运算符优先级
https://www.sojson.com/operation/php.html递增递减> ! > 算术运算符 > 大小比较 > (不)相等比较 > 引用 > 位运算符(^)>位运算符(|)>逻辑与>逻辑或>三目 > 赋值 > and >xor > or
括号的使用可以增加代码可读性,推荐使用 - 比较运算符
== 和 ===的区别
等值判断(false的七种情况) - 递增递减运算符
递增、递减运算符不影响布尔值
递减NULL值没有效果
递增NULL值为1
递增和递减在前就先运算后返回,反之就先返回,后运算 - 逻辑运算符
短路作用
$a = true || $b ==3;
$b = false && $a == 1;
||和&&与or和and的优先级不同
$a = false || true; //$a=true
$b = false or true; $b = false
重点记忆递增、递减运算符的运算规则,逻辑运算符的短路效果,在看到逻辑运算符要多考虑优先级问题
六. 流程控制
- 遍历数组的三种方法及区别
for 只能遍历索引数组
foreach 遍历索引和关联数组
list() each() while() 遍历索引和关联数组,
list() each() while()组合,不会reset()
foreach遍历会对数组进行reset()操作
- if…elseif
在elseif语句中只能有一个表达式为true,即在elseif语句中只能有一个语句块被执行,多个elseif从句是排斥关系。
使用elseif语句有个基本原则,总把优先范围小的条件放在前面处理。 - switch case
和if不同,switch后面的控制表达式的数据类型只能是整形、浮点型或者字符串
continue语句作用到switch的作用类似于break
跳出switch外的循环,可以使用continue 2
面试真题
PHP如何优化多个if…elseif语句?
将可行性大的放在前面
使用switch代替
七. 自定义函数、内部函数
- 变量作用域
变量的作用域也称变量的范围,变量的范围即它定义的上下文背景(生效范围)。大部分的PHP变量只有一个单独的范围。这个单独的范围跨度同样包含了include和require引入的文件。
global 将函数外部的变量引入函数内部
$GLOBALS[’’]
- 静态变量
静态变量仅在局部函数域中存在,但当程序执行离开此作用域时,其值并不会消失。
static关键字
(1)仅初始化一次
(2)初始化时需要赋值
(3)每次执行函数该值会保留
(4)static修饰的变量是局部变量,仅在函数内部有效
(5)可以记录函数的调用次数,从而可以在某些条件下终止递归
八. 函数的返回值
- 值通过使用可选的返回语句return 返回
可以返回包括数组和对象的任意类型
返回语句会终止函数执行,将控制器交给函数调用处
省略return,返回值为null,不可能有多个返回值 - 函数的引用返回
从函数返回一个引用,必须在函数声明和指派返回值给一个变量时都使用引用运算符&
function myFun(){
static $b = 10;
return $b;
}
$a = myFun();//10
$a = &myFun();//让$a和$b互为引用
$a = 100;
echo myFun();//100
九. 外部文件的导入
include/require语句包含并运行指定文件
如果给出路径名按照路径来找,否则从include_path中查找
如果include_path中也没有,则从调用脚本文件所在的目录和当前工作目录下寻找
当一个文件被包含时,其中所包含的代码继承了include所在行的变量范围
加载过程中未找到文件,则include结构会发出一条警告;require会发出一个致命错误
require(include)/require_once(include_once)唯一区别是php会检查该文件是否已经被包含过,如果是则不会再次包含。
十. 系统内置函数
- 时间日期函数
date() strtotime() mktime() time() microtime() date_default_timezone_set(‘PRC’) - IP处理函数
ip2long() long2ip() - 打印处理
print
printf() 根据指定的格式将参数输出到屏幕上
print_r() 一般用于打印数组、对象,格式化输出
echo 打印字符串,可以打印多个
sprintf() 根据指定的格式将参数输出到指定的字符数组中
var_dump() 打印类型和值
var_export() 将数组格式化输出 - 序列号和反序列化
serialize() unserialize() - 字符串处理函数
implode() explode() join() strrev() trim() ltrim() rtrim() strstr() number_format() - 数组处理函数
array_keys() array_values() array_diff() array_intersect() array_merge() array_shift() array_unshift() array_pop array_push() sort()
实战
$var1 = 5;
$var2 = 10;
function foo(&$my_var)
{
global $var1;//5
$var1 +=2;//7
$var2 = 4;//4
$my_var += 3;//8
return $var2;//4
}
$my_var = 5;
echo foo($my_var)."\n";//4
echo $my_var."\n";//8
echo $var1;//7
echo $var2;//10
$bar = 'foo';
$my_var = 10;
echo $bar($my_var)."\n";//4
十一. 正则表达式
面试题
手机号正则表达式
1. 写出要匹配的字符串
13988888888
2. 自左向右的顺序使用正则表达式的原子和元字符进行拼接
$pattern = '/^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\d{8}$/';
preg_match($pattern,$phone,$match);
正则表达式作用:分割、查找、匹配、替换字符串
1.分隔符:正斜线(/) hash符号(#) 取反符号(~)
通用原子: \d \D \w \W \s \S
元字符:. * ? ^ $ + {n} {n,} {n,m} [] () [^] | [-]
模式修正符 i m e s U x A D u
- 后向引用
$str = '<b>abc</b><b>efd</b>';
$pattern = '/<b>(.*?)<\/b>/';
preg_replace($pattern,'\\1',$str);
- 贪婪模式
$str = '<b>abc</b><b>bcd</b>';
$pattern = '/<b>(.*?)<\/b>/';
$pattern = '/<b>(.*)<\/b>/U';
preg_replace_all ($pattern,'\\1',$str);
- 中文匹配
UTF-8汉字编码范围0x4e00-0x9fa5,在ANSI(gb2312)环境下,0xb0-0xf7,0xa1-0xfe
UTF-8要使用u模式修正符使模式字符串被当成UTF-8,在ANSI(gb2312)环境下,要使用chr将ascii码转换为字符
$str = '中文';
utf-8编码内容的匹配
$pattern = '/[\x{4e00}-\x{9fa5}]+/u';
gdk编码内容的匹配
$pattern = '/['.chr(0xb0).'-'.chr(0xf7).']['.chr(0xa1).'-'.chr(0xfe).']/';
preg_match($pattern,$str,$match);
var_dump($match);
解题思路
先写出一个要匹配的字符串
自左向右的顺序使用正则表达式的原子和元字符进行拼接
最终加入模式修正符
十二. 文件读取写入操作
fopen()函数
打开一个文件,打开时需要指定打开模式
打开模式: r/r+ w/w+ a/a+ x/x+ b t
写入函数
fwrite
读取函数
fread()
fgets()
fgetc()
关闭文件
fclose()
不需要fopen()打开的函数
file_get_contents()
file_put_contents()
其他读取函数
file()
readfile()
访问远程文件
开启allow_url_fopen,HTTP协议连接只能使用只读,FTP协议可以使用只读或者只写
名称相关:
basename()
dirname()
pathinfo()
目录读取
opendir()
readdir()
closedir()
rewinddir()
目录删除
rmdir()
目录创建
mkdir()
文件大小
filesize()
目录大小
disk_free_space()
disk_total_space()
文件拷贝
copy()
删除文件
unlink()
文件类型
filetype()
重命名文件或者目录
rename()
文件截取
ftruncate()
文件属性
file_exists() is_readable() is_writable() is_executable() filectime() fileatime() filemtime()
文件锁
flock()
文件指针
ftell() fseek() rewind()
面试题:
- 重复将字符串写入文件开头
$file = 'hello.txt';
$handle = fopen($file,'r');
$content = fread($handle,filesize($file));
$content = 'hello world'.$content;
$fclose($handle);
$handle = fopen($file,'w');
fwrite($handle,$content);
fclose($handle);
- 遍历目录,输出所有文件
function loopDir($dir)
{
$handle = opendir($dir);
while(false !== ($file = readdir($handle)))
{
if($file != '.' && $file != '..')
{
if(filetype($dir.'/'.$file) == 'dir')
{
loopDir($dir.'/'.$file);
}
if(filetype($dir.'/'.$file) == 'file'){
echo $file."\n";
}
}
}
}
十三. 会话控制
- 为什么使用会话控制
http协议无状态,会话控制允许服务器跟踪同一客户端的进行的连续请求。 - 实现方式
通过GET参数传递
Cookie 存储在客户端的数据信息 - cookie操作
设置
setcookie($name,$value,$expire,$path,$domain,$secure);
读取
$_COOKIE
设置数组类型
setcookie('a[b]','val')
删除
setcookie($name,'',time()-1)
- cookie优点和缺点
(1)保存在客户端,不占用服务器资源
(2)不安全,而且用户可以禁用 - Session 的操作
session_start();
$_SESSION;
$_SESSION=[];
session_destroy();
- session配置
session.auto_start
session.cookie_domain
session.cookie_lifetime
session.cookie_path
session.name
session.save_path
session.use_cookies
session.use_trans_sid
session.gc_probability =1
session.gc_divisor = 100
session.gc_maxlifetime = 1440
session.save_handler
- session的优点和缺点
优点:安全
缺点:占用服务器资源
传递Session_ID问题
<a href="1.php?<?php echo session_name().'='.session_id() ?>">下一页</a>
十四. 面向对象
- php的类权限控制修饰符
public 类内部、外部、子类使用
protected 类内部、子类中使用
private 类内部使用 - 封装、继承、多态
封装通过成员修饰符实现
继承:单一继承,方法重写
多态:
抽象类的定义,如果类中有抽象方法,一定要定义成抽象类
接口的定义,没有方法体 - 魔术方法
__construct() __destruct() __call() __callStatic() __get() __set() __isset() __unset() __sleep() __wakeup() __toString() __clone()
- 设计模式
工厂模式、单例模式、注册树模式、适配器模式、观察者模式、策略模式
重点:记忆面向对象基本语法、记忆魔术方法、理解常见设计模式
十五. 网络协议
- HTTP协议状态码
五类响应:
1XX(信息类状态码,表示接收请求正在处理)
2XX(请求成功状态码,正常响应)
200 204(服务器已正常处理请求,但在响应的报文中不含实体的主体部分) 206(响应部分请求)
3XX(需要附加操作以完成请求)
301(永久性重定向) 302(临时重定向) 303(请求资源存在另一个URI,使用get方法,定向获取资源)
304(Not Modified(未修改) 客户的缓存资源是最新的, 要客户端使用缓存)
4XX(客户端错误,服务器无法处理请求)
400(Bad Request(坏请求) 告诉客户端,它发送了一个错误的请求。)
401(Unauthorized(未授权)需要客户端对自己认证)
403(Forbidden(禁止) 请求被服务器拒绝了)
404(Not Found(未找到)未找到资源)
5XX(服务器错误)
500(内部服务器错误,服务器遇到一个错误,使其无法为请求提供服务)
503(未提供此服务,服务器目前无法为请求提供服务,但过一段时间就可以恢复服务) - OSI七层模型
第一层 物理层
建立、维护、断开物理连接
第二层 数据链路层
建立逻辑连接、进行硬件地址寻址、差错校验等功能
第三层 网络层
进行逻辑地址寻址,实现不同网络之间的路径选择
第四层 传输层
定义传输数据的协议端口号,以及流控和差错校验。
协议有:TCP UDP,数据包一旦离开网卡即进入网络传输层
第五层 会话层
建立、管理、终止会话
第六层 表示层
数据的表示、安全、压缩
第七层 应用层
网络服务与最终用户的一个接口
协议有:HTTP80 FTP21 TFTP SMTP25 SNMP DNS TELNET23 HTTPS443 POP3110 DHCP - HTTP协议的工作特点和工作原理
工作特点
基于B/S模式
通信开销小、简单快速、传输成本低
使用灵活、可使用超文本传输协议
节省传输时间
无状态
工作原理
客户端发送请求给服务器,创建一个TCP连接,指定端口号,默认80,连接到服务器,服务器监听浏览器请求,一旦监听到客户端请求,分析请求类型后,服务器会向客户端返回状态信息和数据内容
- HTTP协议常见请求和响应头
Content-Type,Accept,Origin,Cookie,Cache-Control,User-Agent,Referrer,X-Forwarded-For,Access-Control-Allow-Origin,Last-Modified - HTTP协议请求方法
GET POST HEAD OPTIONS PUT DELETE TRACE - HTTP协议和GET和POST请求方式的区别
http://www.w3school.com.cn/tags/html_ref_httpmethods.asp (1)GET 从指定的资源请求数据,POST 向指定的资源提交要被处理的数据
(2) GET 请求可被缓存,POST 请求不会被缓存
(3)GET 请求保留在浏览器历史记录中,POST 请求不会保留在浏览器历史记录中
(4)GET 请求可被收藏为书签,POST 不能被收藏为书签
(5)GET 请求有长度限制,POST 请求对数据长度没有要求
(6)GET 请求不应在处理敏感数据时使用 - HTTPS的工作原理
HTTPS是一种基于SSL/TLS的HTTP协议,所有的HTTP数据都是在SSL/TLS协议封装之上传输的。
HTTPS协议在HTTP协议的基础上,添加了SSL/TLS握手以及数据加密传输,也属于应用层协议。 - 常见的网络协议含义及端口
FTP(文件传输协议,端口21) Telnet(用于远程登录,端口23) SMTP(发送邮件协议,端口25) POP3(接收邮件协议,端口110) HTTP(超文本传输协议,端口80)
DNS(解析域名,端口53)
十六. 开发环境、配置
- 版本控制软件
集中式和分布式
集中式(CVS和SVN)
只在中央服务器存在版本库信息,断网即无法使用
分布式(Git)
每个终端都有一个版本库,断网照样可以保存版本,容灾性更好 - PHP运行原理
Nginx+PHP-FPM
CGI:为了解决不同语言的解析器与web服务器通信问题,只要按照CGI协议编写程序就能够实现语言解析器跟web服务器的通讯。
PHP-CGI:建立PHP解析器和web服务器通信的桥梁.
FastCGI:优化的CGI,因为我们web服务器没接收到一个请求,都会fork一个CGI进程,请求结束后再结束掉这个进程。当我们有很多web请求时,就会同时fork和kill掉很多进程,非常浪费资源。FastCGI处理完请求后不会kill进程,还会继续处理新的请求,从而大大提高效率。
PHP-FPM:是FastCGI的进程管理器。是FastCGI的一个实现,并且提供进程管理的功能,包含master进程和work进程,master进程只有一个,负责监听端口,接收来自web服务器的请求。work进程会有多个,每个都会启动一个PHP解析器,用于处理PHP代码。 - PHP常见配置项
register_globals,allow_url_fopen,allow_url_include,date.timezone,display_errors,error_reporting,safe_mode,upload_max_filesize,max_file_uploads,post_max_size