[TOC]
# 1. PHP引用变量的概念以及定义方式
概念:在PHP中引用意味着用不同的名字访问同一个变量的内容。
定义方式:`&`
工作原理:
```php
<?php
// 定义一个变量
$a = range(0, 1000);
var_dump(memory_get_usage());
// 定义变量b,并把a赋值给b
// COW Copy On Write
$b = $a; // $b 与 $a共享一块空间
var_dump(memory_get_usage());
// 对a进行修改
$a = range(0, 1000); // 有修改,会Copy $a空间
var_dump(memory_get_usage());
```
> memory_get_usage():查看使用的内存空间
> COW:对变量进行修改才会Copy,但是对对象象的属性进行修改时不会进行复制,
> 所以内存表现如下:
在内存中表现形式如下:

```php
// 定义一个变量
$a = range(0, 1000);
// 定义变量b,并把a赋值给b
$b = &$a;
// 对a进行修改
$a = range(0, 1000);
```
在内存中表现形式如下:

说明:
> ① unset():只会取消引用,而不会销毁空间
> ② 对象本身就是引用传递
**实例**
写出下列程序的输出结果。
```php
$data = ['a', 'b', 'c'];
foreach ($data as $key=>$val) {
$val = &$data[$key];
}
```
+ 每一次循环结束后,$data的值是什么?
+ 程序执行完了之后,变量$data的值是什么? ['b', 'c', 'c']

# 2. 常量及数据类型
## 数据类型(8大数据类型)

## 字符串
PHP中字符串可以使用哪三种定义方式?他们之间的区别。
+ ''
+ ""
+ heredoc和newdoc
区别:
单引号:
+ 单引号不能解析变量
+ 单引号不能解析转义字符,只能解析单引号和反引号本身
+ 变量和变量、变量和字符串、字符串和字符串之间可以使用`.`连接
双引号:
+ 双引号可以解析变量,变量可以使用特殊字符(如:&)和`{}`包含
+ 双引号可以解析所有转义字符
+ 字符串连接
> 单引号的效率高于双引号。
heredoc:类似于双引号
```php
$str = <<<EOT
内容
EOT;
```
newdoc:类似于单引号
> heredoc和newdoc都是用来处理大文本的。
## 常量
定义常量
+ const
+ define
> ① `const`更快,是语言结构,而`define`是函数。
> ② `define`不能用于类常量的定义,`const`可以
> ③ 常量一经定义,不能被修改、删除
预定义常量(魔术常量):
+ `__FILE_`_:文件的完整路径和文件名
+ `__LINE__`:文件中当前行号
+ `__DIR__`:文件所在目录
+ `__FUNCTION__`:函数名称
+ `__CLASS__`:类的名称
+ `__TRAIT__`:Trait的名字
+ `__METHOD__`:类的方法名称
+ `__NAMESAPCE__`:当前命名空间的名称
真题:
+ 用PHP写出显示客户端IP和服务器IP的代码。
+ `__FILE__`表示什么意思?
```php
// 客户端IP
$_SERVER['REMOTE_ADDR'];
$_SEVER['SERVER_ADDR'];
`__FILE_`_:文件的完整路径和文件名
```
# 3. 运算符
真题:
`foo()`和`@foo()`之间的区别。
@:错误控制符。
当将放置在一个PHP表达式之前,则该表达式可能产生的**任何错误**信息都会被**忽略掉**。
## 运算符的优先级

文档地址:[官方文档](http://php.net/manual/zh/language.operators.precedence.php)

## 比较运算符
==和===的区别
等值判断(false的7种情况)
## 递增/递减运算符
+ 递增/递减运算符不影响**布尔值**(true++无效)
+ **增减NULL**值没有效果
+ **递增NUL**L值为1
+ i++/++i
## 逻辑运算符
+ 短路作用
+ ||、&&与or、and的优先级不同
```php
$a == true || $b == 3 // 前面为true,后面的不会执行了
```
# 4. 流程控制
遍历数组的三种方式及各自的区别。
+ for
+ foreach
+ while、list()、each()组合
for只能遍历索引数组,foreach可以遍历索引、关联数组,联合使用list()、each()和while同样可以遍历索引、关联数组。
> while、list()、each()组合不会reset()重置
> foreach会对数组进行reset()操作
分支结构:
+ if
+ if ... else ...
+ switch ... case
# 5. 自定义函数和内部函数
真题:
写出以下程序的输出结果:
```php
$count = 5;
function get_count () {
static $count; // 局部变量,没有初始化值,为null
return $count++; // null++ == 1,因为++在后面,所以第一次调用这返回null
}
echo $count; // 5
++$count; // 6
echo get_count(); // NULL-->不会输出
echo get_count(); // 1
```
结果:
> 51
考点:
+ 变量的作用域和静态变量
+ 延伸:函数的参数以及参数的引用传递
+ 延伸:函数的返回值及引用返回
+ 延伸:外部文件的引入
+ 延伸:系统内置的函数
## 变量的作用域及静态变量
### 变量的作用域
变量的作用域:也称变量的范围,变量的范围即它定义的上下文背景。大部分的PHP变量是有一个单独的范围。这个单独的范围跨度同样包含`include`和`require`引入的文件。
+ global
+ $GLOBALS超全局数组
~~~
$str = "outer"; // 全局变量
function fun() {
echo $str; // 局部变量,这里会报错Undefined variable
}
fun();
~~~
如果要在函数内部使用$str变量,我们可以使用`global`关键字。
~~~
$str = "outer"; // 全局变量
function fun() {
global $str;
// 以下两种方式都可以用
echo $str;
echo $GLOBALS['str'];
}
fun();
~~~
### 静态变量
静态变量仅在局部函数中存在,但当程序执行离开此作用域时,其值并不会消失。
static修饰的变量的特点:
+ 仅初始化一次
+ 初始化时需要赋值
+ 每次执行函数该值会保留
+ static 修饰的变量是局部的,仅在函数内部有效
+ 可以记录函数的调用次数,从而可以在某些条件下终止递归
```php
function fun() {
static $a = 1; // 只会申明一次
echo $a++;
}
fun(); // 1
fun(); // 2
fun(); // 3
```
## 函数的参数以及参数的引用传递
### 函数的参数
默认情况下,函数的参数通过值传递。
如果希望允许函数修改它的值,必须通过引用传递参数。
** 值传递:**
```php
$a = 1;
function func( $a ) {
$a = 2;
}
func( $a );
echo $a; // 1
```
在函数内部,修改不了全局变量`$a`的值
**引用传递**
```php
$a = 1;
function func( &$a ) {
$a = 2;
}
func( $a );
echo $a; // 2
```
修改了全局变量`$a`的值
## 函数的返回值及引用返回
返回值:
值通过使用可选的返回语句(return)返回
可以返回包括数组和对象的任意类型
返回语句会中止函数的执行,将控制权交回函数调用处
省略return,返回值为NULL,不可返回多个值
引用返回:
从函数返回一个引用,必须在函数申明和指派返回值给一个变量是都使用引用运算符`&`。
```php
function &a() {
static $b = 10;
return $b;
}
echo a(); // 10,函数正常调用
$a = &a();
$a = 100;
echo $a; // 100
```
## 延伸:外部文件的引入
include、require语句包含并运行指定文件
如果给出路径名按照路径来找,否则从include_path中查找;如果include_path中没有,则从调用脚本文件所在的目录和当前工作目录下寻找。
当一个文件被包含时,其中所包含的代码继承了include所在行的变量范围。
加载过程中未找到文件则**include**结构会发出一个**警告**,而**require**则会发出一个**致命错误**。脚本终止。
require(include)/ require_onece(include_once)唯一的区别是PHP会检查该文件是否已经被包含过,如果是则不会再次包含。
## 延伸:系统内置的函数
### 时间日期函数
date()、strtotime()、mktime()、time()、microtime()、date_default_timezone_set()
### IP处理
ip2long()、long2ip()
### 打印处理
print()、printf()、print_r()、echo、sprintf()、var_dump()、var_export()
var_dump():会打印出数据类型
print_r():标量类型则原来的值,将数组格式化输出
var_export():返回的结果与print_r()类似,但是`var_export()`返回的是合法的PHP代码(返回的值可以当做数据使用)
### 字符串处理函数
implod()、explode()、join()、strtev()、trim() ...
### 数组处理函数
array_keys()、array_values()、array_diff() ...
# 6. 正则表达式
作用:分割、查找、匹配、替换。

## 后向引用
```php
$str = "<b>abc</b>";
$pattern = '/<b>(.*)<\/b>/';
$a = preg_replace($pattern, '\\1', $str);
echo $a;
```
## 贪婪模式
~~~
$str = "<b>abc</b><b>def</b>";
$pattern = '/<b>.*?<\/b>/';
$a = preg_replace_all($pattern, '\\1', $str);
~~~
## 常见的正则函数
preg_match()、preg_match_all()、preg_replace()、preg_split()
## 中文匹配
UTF-8汉字编码范围是**0x4e00-0x9fa5**,需要使用**u模式修正符**;
ANSI(gb2312)环境下:**0xb0-0xf7,0xa1-0xfe**,需要使用chr将ASCII码转换为字符。
~~~
$str = "中文";
$pattern = '/[\x{4e00}-\x{9fa5}]+/u'; // UTF-8
$pattern = '/['.chr(0xb0).'-'.chr(0xf7).']['.chr(0xa1).'-'.chr(0xfe).']/'; //GB2312
preg_match($pattern, $str, $m);
var_dump($m);
/**
* array(1) {
[0]=>string(6) "中文"
}
*/
~~~
常见的正则表达式:URL、Email、IP、手机号
栗子:
匹配所有`img`标签中的src的值。
~~~
$img = '<img alt="image" id="nav" src="av.png"/>';
$pattern = '/<img.*?src="(.*?)".*?\/?>/i';
preg_match($pattern, $img, $ma);
var_dump($ma);
/**
array(2) {
[0]=>string(40) "<img alt="image" id="nav" src="av.png"/>"
[1]=>string(6) "av.png"
}
*/
~~~
# 7. 文件及目录处理
## 文件读取/写入
fopen():打开一个文件,打开模式——`r/r+`、`w/w+`、`a/a+`、`x/x`、`b`、`t`
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_freee_space()、disk_total_space()
文件拷贝:copy()
删除文件:unlink()
文件类型:filetype()
重命名文件或者目录:rename()
文件截取:ftruncate()
文件属性:file_exists()、is_readable()、is_writable()、is_executable()、filectime()、fileatime()、filemtime()
文件锁:flock()
文件指针:ftell()、fseek()、rewind()
## 真题
将文件的内容读取出来,在开头文件加入Hello World
~~~
$file = './04.php';
$handle = fopen($file, 'r');
$content = fread($handle, filesize($file));
$content = 'Hello World'.$content;
fclose($handle);
$handle = fopen($file, 'w');
fwrite($handle, $content);
fclose($handle);
~~~
通过PHP函数的方式目录进行遍历
~~~
$dir = './test';
function loopDir($dir){
$handle = opendir($dir);
while (false != ($file = readdir($handle))) {
if ($file != '.' && $file != '..') {
echo $file."\n";
if (filetype($dir.'/'.$file) == 'dir' ) {
loopDir($dir.'/'.$file);
}
}
}
}
loopDir($dir);
~~~
# 8. 会话控制
实现方式:
+ GET参数传递(不建议使用)
+ Cookie(存储在客户端浏览器)
+ Session(存储在服务器)
## Cookie
### 操作
+ 设置:setcookie($name, $value, $expire, $path, $domain, $secure, $httponly)
+ 读:$_COOKIE
+ 删除:setcookie($name, '', now()-1000)
### 优点和缺点
缺点:
+ 大小被限制
+ 不安全,有用户篡改cookie的风险
+ 用户禁用cookie,则该功能失效
优点:
+ 不消耗服务器的任何资源
+ 数据持久性
+ 可配置cookie到期规则
## Session
Session是基于Cookie的。存储在服务器。
### 操作
+ 开启session:session_start()
+ $_SESSION
+ 清空SESSION:$_SSEION = []
+ 销毁session文件:session_destroy()
### SESSION配置
session.auto_start = 0
session.cookie_path = /
session.cookie_domain =
session.name
session.save_path
session.use_cookies
session.use_trans_sid
/*垃圾回收*/
session.gc_probability
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.save_handler = files
### Session的优点和缺点
优点:安全
缺点:占用系统资源、分布式问题(使用Redis)
# 9. 面向对象
## PHP的类全新控制修饰符
+ public
+ protected
+ private
## 延伸:面向对象的封装、继承、多态
封装:成员访问权限控制
继承:单一继承、方法重写(Parent::)
多态:抽象类的定义、接口的定义
## 延伸:魔术方法
+ __construct()
+ __destruct()
+ __call()
+ __callStatic()
+ __get()
+ __set()
+ __isset()
+ __unset()
+ __sleep()
+ __wakeup()
+ __toString()
+ __clone()
## 延伸:设计模式
常见的设计模式:工厂模式、单例模式、注册树模式、适配器模式、观察者模式、策略模式。
# 10. 网络协议
## 真题
HTTP/1.1中,状态码 200、301、304、403、404、500的含义
## HTTP协议状态码
负责HTTP响应的返回结果,标记服务器端的处理是否正常,通知发生的错误。
五大类:
+ 1xx:信息类状态码
+ 2xx:成功状态码
+ 3xx:重定向
+ 4xx:客户端请求错误
+ 5xx:服务器错误
创建的状态码:
+ 200、204、206
+ 301、302、303、304、307
+ 400、401、403、404、
+ 500、503
## 延伸:OSI七层模型
物数网传会表应
物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
+ 物理层:建立、维护、断开物理连接
+ 数据链路层:建立逻辑连接、进行硬件地址寻址、差错校验等功能
+ 网络层:进行逻辑地址寻址、实现不同网络之间的路径选择
+ 传输层:定义传输数据的协议端口、以控制和差错校验,协议有:TCP、UDP
+ 会话层:建立、管理、终止会话
+ 表示层:数据的表示、安全、压缩
+ 应用层:网络服务与用户的接口。常见的协议:HTTP、FTP、TFTP、SMTP、SNMP、DNS、HTTPS ...
## 延伸:HTTP协议的工作特点和工作原理
工作特点:
+ 基于B/S模式
+ 通信开销小、简单快递、传输成本低
+ 使用灵活、可食用超文本传输协议
+ 节省存储时间
+ 无状态
工作原理:

## 延伸:HTTP协议常见请求/响应头和请求方法
HTTP协议常见请求/响应头
+ Content-Type
+ Accept
+ Origin
+ Cookie
+ Cache-Control
+ User-Agent
+ Referrer
+ X-Forwarded-For
+ Accsess-Control-Allow-Origin
+ Last-Modified
请求方法
+ GET:一般用于获取数据
+ POST:向指定资源提交数据进行处理请求。一般用于数据提交
+ HEAD:类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
+ OPTIONS:允许客户端查看服务器的性能。可以测试服务器功能是否正常
+ PUT:一般用于修改
+ DELETE:删除
+ TRACE:回显服务器收到的请求,主要用于测试或诊断。
GET和POST区别:
+ 在后退或刷新操作时,GET是无害的,而POST是会重新提交数据
+ GET可以被收藏为书签、POST不可以
+ GET可以被浏览器缓存,而POST不可以被浏览器缓存
+ GET会保存在浏览器历史记录
+ GET的长度限制(URL),最多有2048个字符,而POST没有限制
+ GET只允许ASCII,而POST没有限制
+ GET的不安全,数据对所有人可见
## 延伸:HTTPS协议的工作原理
HTTPS是基于SSl/TLS的http协议,所有的HTTP数据都是在SSL/TLS协议之上传输的。
HTTPS协议在HTTP协议基础上,添加了SSL/TLS握手以及数据加密传输,也属于应用层协议。
## 延伸:常见网络协含义及端口
FTP、Telnet、SMTP、POP3、HTTP、DNS
+ FTP: 文件传输协议,默认端口21
+ Telnet:用于远程登录的协议,默认端口23
+ SMTP:简单邮件传输协议,默认端口25
+ POP3:邮局协议版本3,接受邮件,默认端口110
+ HTTP:超文本传输协议,默认端口80
+ DNS:域名解析服务,端口53
# 11. 开发环境及配置
## 版本控制软件
集中式(CVS、SVN)、分布式(Git)
## PHP的运行原理
Nginx+PHP-FPM
CGI:
FastCGI:CGI的改良版本
PHP-FPM:FastCGI的进程管理
## PHP常见配置项

