企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
# php更新内容 [php4变化日志](https://www.php.net/ChangeLog-4.php)(主要是修复bug方面) [php5变化日志](http://php.net/ChangeLog-5.php) (主要是修复bug方面) [php7变化日志](http://php.net/ChangeLog-7.php)(主要是修复bug方面) [更新日志](https://www.php.net/manual/zh/doc.changelog.php)(绑定的扩展的函数更新内容) [迁移日志(包含新增或废弃的特性和函数等)](https://www.php.net/manual/zh/appendices.php) 主要新特性一览,详情查看迁移日志 # **php5.4新特性** ## **增加短数组支持如:\[1, 2, 3, 4\]** ## **新增Trait** # **php5.5新特性** ## **新增yield关键字简化生成器** **新增密码加密及验证** ``` <pre class="calibre10">``` <span class="token">//之前</span> <span class="token">//模拟input提交的密码</span> $user_input <span class="token1">=</span> <span class="token2">'12+#æ345'</span><span class="token3">;</span> <span class="token">//crypt()函数不能正确处理加号。请首先对密码使用urlencode,以确保登录过程可以处理任何字符</span> $pass <span class="token1">=</span> <span class="token4">urlencode</span><span class="token3">(</span>$user_input<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> $pass_crypt <span class="token1">=</span> <span class="token4">crypt</span><span class="token3">(</span>$pass<span class="token3">)</span><span class="token3">;</span> <span class="token5">if</span> <span class="token3">(</span>$pass_crypt <span class="token1">==</span> <span class="token4">crypt</span><span class="token3">(</span>$pass<span class="token3">,</span> $pass_crypt<span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> echo <span class="token2">"成功!有效的密码"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token5">else</span> <span class="token3">{</span> echo <span class="token2">"无效的密码"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//当校验密码时,应该使用一个不容易被时间攻击的字符串比较函数来比较crypt()的输出与之前已知的哈希。出于这个目的,PHP5.6开始提供了hash_equals()</span> $hashed_password <span class="token1">=</span> <span class="token4">crypt</span><span class="token3">(</span><span class="token2">'mypassword'</span><span class="token3">)</span><span class="token3">;</span> <span class="token">// 自动生成盐值</span> <span class="token">/* 你应当使用 crypt() 得到的完整结果作为盐值进行密码校验,以此来避免使用不同散列算法导致的问题。(如上所述,基于标准 DES 算法的密码散列使用 2 字符盐值,但是基于 MD5 算法的散列使用 12 个字符盐值。)*/</span> <span class="token5">if</span> <span class="token3">(</span><span class="token4">hash_equals</span><span class="token3">(</span>$hashed_password<span class="token3">,</span> <span class="token4">crypt</span><span class="token3">(</span>$user_input<span class="token3">,</span> $hashed_password<span class="token3">)</span><span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> echo <span class="token2">"Password verified!"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//新特性</span> <span class="token">/** * 我们想要使用默认算法散列密码 * 当前是 BCRYPT,并会产生 60 个字符的结果。 * * 请注意,随时间推移,默认算法可能会有变化, * 所以需要储存的空间能够超过 60 字(255字不错) * 强烈建议不要自己为这个函数生成盐值(salt)。只要不设置,它会自动创建安全的盐值 * password_hash 参数2有三个加密算法:PASSWORD_DEFAULT(默认),PASSWORD_BCRYPT ,PASSWORD_ARGON2I(php7.2加入) */</span> $hash<span class="token1">=</span><span class="token4">password_hash</span><span class="token3">(</span><span class="token2">"rasmuslerdorf"</span><span class="token3">,</span> PASSWORD_DEFAULT<span class="token3">)</span><span class="token3">;</span><span class="token">//$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a</span> <span class="token5">if</span> <span class="token3">(</span><span class="token4">password_verify</span><span class="token3">(</span><span class="token2">'rasmuslerdorf'</span><span class="token3">,</span> $hash<span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> echo <span class="token2">'Password is valid!'</span><span class="token3">;</span> <span class="token3">}</span> <span class="token5">else</span> <span class="token3">{</span> echo <span class="token2">'Invalid password.'</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">print_r</span><span class="token3">(</span>password_get_info <span class="token3">(</span>$hash<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//Array ( [algo] => 1 [algoName] => bcrypt [options] => Array ( [cost] => 10 ) )</span> ``` ``` ![](https://img.kancloud.cn/3c/2d/3c2d9a4794eb4a29661e8fa507b0c4ab_1384x376.png) password\_hash方法我们无需关注salt,只需要将password\_hash返回的hash保存在数据库就ok ``` <pre class="calibre10">``` $_POST<span class="token3">[</span><span class="token2">'pwd'</span><span class="token3">]</span><span class="token1">==</span> <span class="token2">'rasmuslerdorf'</span><span class="token3">;</span> $password <span class="token1">=</span>$_POST<span class="token3">[</span><span class="token2">'pwd'</span><span class="token3">]</span><span class="token3">;</span> <span class="token">//数据库没有就使用password_hash,数据库有则查查出数据库的hash</span> <span class="token5">if</span><span class="token3">(</span><span class="token1">!</span><span class="token4">empty</span><span class="token3">(</span>$res<span class="token1">=</span><span class="token4">findPwdToMysql</span><span class="token3">(</span>$_POST<span class="token3">[</span><span class="token2">'user'</span><span class="token3">]</span><span class="token3">,</span> $_POST<span class="token3">[</span><span class="token2">'pwd'</span><span class="token3">]</span><span class="token3">)</span><span class="token3">)</span><span class="token3">)</span><span class="token3">{</span> $hash<span class="token1">=</span>$res<span class="token3">;</span> <span class="token3">}</span><span class="token5">else</span><span class="token3">{</span> $hash<span class="token1">=</span><span class="token4">password_hash</span><span class="token3">(</span>$password<span class="token3">)</span><span class="token3">;</span><span class="token">//$2y$10$YCFsG6elYca568hBi2pZ0.3LDL5wjgxct1N8w/oLR/jfHsiQwCqTS</span> <span class="token4">savePwdTosql</span><span class="token3">(</span>$hash<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">// 当硬件性能得到改善时,cost 参数可以再修改(默认10)</span> $options <span class="token1">=</span> <span class="token4">array</span><span class="token3">(</span><span class="token2">'cost'</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">11</span><span class="token3">)</span><span class="token3">;</span> <span class="token">// 根据明文密码验证储存的散列</span> <span class="token5">if</span> <span class="token3">(</span><span class="token4">password_verify</span><span class="token3">(</span>$password<span class="token3">,</span> $hash<span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> <span class="token">// 检测是否有更新的可用散列算法</span> <span class="token">// 或者 cost 发生变化</span> <span class="token5">if</span> <span class="token3">(</span><span class="token4">password_needs_rehash</span><span class="token3">(</span>$hash<span class="token3">,</span> PASSWORD_DEFAULT<span class="token3">,</span> $options<span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> <span class="token">// 如果是这样,则创建新散列,替换旧散列</span> $newHash <span class="token1">=</span> <span class="token4">password_hash</span><span class="token3">(</span>$password<span class="token3">,</span> PASSWORD_DEFAULT<span class="token3">,</span> $options<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">// 使用户登录setcookie()</span> <span class="token3">}</span> ``` ``` **访问单个元素和字符** ``` <pre class="calibre10">``` <span class="token">//之前</span> $arr<span class="token1">=</span><span class="token3">[</span><span class="token6">123</span><span class="token3">]</span><span class="token3">;</span> $str<span class="token1">=</span><span class="token2">'abc'</span><span class="token3">;</span> $arr<span class="token3">[</span><span class="token6">0</span><span class="token3">]</span><span class="token3">;</span> $str<span class="token3">[</span><span class="token6">0</span><span class="token3">]</span><span class="token3">;</span> <span class="token">//新特性:</span> <span class="token3">[</span><span class="token6">123</span><span class="token3">]</span><span class="token3">[</span><span class="token6">0</span><span class="token3">]</span><span class="token3">;</span> <span class="token2">'abc'</span><span class="token3">[</span><span class="token6">0</span><span class="token3">]</span><span class="token3">;</span> ``` ``` foreach控制结构现在支持通过[list()](https://www.php.net/manual/zh/function.list.php)构造将嵌套数组分离到单独的变量 ``` <pre class="calibre10">``` <span class="token">//之前</span> $arr1<span class="token1">=</span><span class="token3">[</span><span class="token6">1</span><span class="token3">,</span><span class="token6">2</span><span class="token3">]</span><span class="token3">;</span> $arr2<span class="token1">=</span><span class="token3">[</span><span class="token6">3</span><span class="token3">,</span><span class="token6">4</span><span class="token3">]</span><span class="token3">;</span> list <span class="token3">(</span>$a<span class="token3">,</span> $b<span class="token3">)</span><span class="token1">=</span>$arr1<span class="token3">;</span> list <span class="token3">(</span>$a<span class="token3">,</span> $b<span class="token3">)</span><span class="token1">=</span>$arr2<span class="token3">;</span> <span class="token">//新特性:</span> $array <span class="token1">=</span> <span class="token3">[</span> <span class="token3">[</span><span class="token6">1</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">]</span><span class="token3">,</span> <span class="token3">[</span><span class="token6">3</span><span class="token3">,</span> <span class="token6">4</span><span class="token3">]</span><span class="token3">,</span> <span class="token3">]</span><span class="token3">;</span> foreach <span class="token3">(</span>$array as <span class="token4">list</span><span class="token3">(</span>$a<span class="token3">,</span> $b<span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> echo <span class="token2">"A: $a; B: $b\n"</span><span class="token3">;</span> <span class="token3">}</span> 输出: A<span class="token3">:</span> <span class="token6">1</span><span class="token3">;</span> B<span class="token3">:</span> <span class="token6">2</span> A<span class="token3">:</span> <span class="token6">3</span><span class="token3">;</span> B<span class="token3">:</span> <span class="token6">4</span> ``` ``` ## **异常处理新增finally块,`try{}catch{}finally{}`** finally块中的代码总是在try和catch块之后执行,不管是否抛出了异常,也不管正常的执行是否继续 # **php5.6 新特性** ## **可变数量的参数** 可变参数由 ... 语法实现;在 PHP 5.5 及更早版本中,使用函数 func\_num\_args(),func\_get\_arg(),和 func\_get\_args() ``` <pre class="calibre10">``` <span class="token">//5.6以前实现可变参数</span> <span class="token5">function</span> <span class="token4">sum</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> $acc <span class="token1">=</span> <span class="token6">0</span><span class="token3">;</span> foreach <span class="token3">(</span><span class="token4">func_get_args</span><span class="token3">(</span><span class="token3">)</span> as $n<span class="token3">)</span> <span class="token3">{</span> $acc <span class="token1">+</span><span class="token1">=</span> $n<span class="token3">;</span> <span class="token3">}</span> <span class="token5">return</span> $acc<span class="token3">;</span> <span class="token3">}</span> echo <span class="token4">sum</span><span class="token3">(</span><span class="token6">1</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">,</span> <span class="token6">3</span><span class="token3">,</span> <span class="token6">4</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//新特性</span> <span class="token5">function</span> <span class="token4">f</span><span class="token3">(</span>$req<span class="token3">,</span> $opt <span class="token1">=</span> <span class="token5">null</span><span class="token3">,</span> <span class="token3">.</span><span class="token3">.</span><span class="token3">.</span>$params<span class="token3">)</span> <span class="token3">{</span> <span class="token">// $params 是一个包含了剩余参数的数组</span> <span class="token4">printf</span><span class="token3">(</span><span class="token2">'$req的值: %d; $opt的值: %d; $params的个数: %d;'</span><span class="token3">,</span> $req<span class="token3">,</span> $opt<span class="token3">,</span> <span class="token4">count</span><span class="token3">(</span>$params<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> echo <span class="token4">gettype</span><span class="token3">(</span>$params<span class="token3">)</span><span class="token3">.</span><span class="token2">"<br>"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">f</span><span class="token3">(</span><span class="token6">1</span><span class="token3">)</span><span class="token3">;</span><span class="token">//$req的值: 1; $opt的值: 0; $params的个数: 0;array</span> <span class="token4">f</span><span class="token3">(</span><span class="token6">1</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">)</span><span class="token3">;</span><span class="token">//$req的值: 1; $opt的值: 2; $params的个数: 0;array</span> <span class="token4">f</span><span class="token3">(</span><span class="token6">1</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">,</span> <span class="token6">3</span><span class="token3">)</span><span class="token3">;</span><span class="token">//$req的值: 1; $opt的值: 2; $params的个数: 1;array</span> <span class="token4">f</span><span class="token3">(</span><span class="token6">1</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">,</span> <span class="token6">3</span><span class="token3">,</span> <span class="token6">4</span><span class="token3">)</span><span class="token3">;</span><span class="token">//$req的值: 1; $opt的值: 2; $params的个数: 2;array</span> <span class="token4">f</span><span class="token3">(</span><span class="token6">1</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">,</span> <span class="token6">3</span><span class="token3">,</span> <span class="token6">4</span><span class="token3">,</span> <span class="token6">5</span><span class="token3">)</span><span class="token3">;</span><span class="token">//$req的值: 1; $opt的值: 2; $params的个数: 3;array</span> ``` ``` 在调用函数的时候,使用...运算符, 将**数组**和**可遍历**对象展开为函数参数。 在其他编程语言,比如 Ruby中,这被称为连接运算符 ``` <pre class="calibre10">``` <span class="token5">function</span> <span class="token4">add</span><span class="token3">(</span>$a<span class="token3">,</span> $b<span class="token3">,</span> $c<span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> $a <span class="token1">+</span> $b <span class="token1">+</span> $c<span class="token3">;</span> <span class="token3">}</span> <span class="token">//add(1,...[2, 3])</span> $operators <span class="token1">=</span> <span class="token3">[</span><span class="token6">2</span><span class="token3">,</span> <span class="token6">3</span><span class="token3">]</span><span class="token3">;</span> echo <span class="token4">add</span><span class="token3">(</span><span class="token6">1</span><span class="token3">,</span> <span class="token3">.</span><span class="token3">.</span><span class="token3">.</span>$operators<span class="token3">)</span><span class="token3">;</span><span class="token">//6 与add(1,2,3)效果一样</span> ``` ``` ## **使用表达式定义常量** ``` <pre class="calibre10">``` <span class="token">//之前只能使用静态值定义常量</span> const ONE <span class="token1">=</span> <span class="token6">1</span><span class="token3">;</span> <span class="token">//现在可以用表达式定义常量</span> const TWO <span class="token1">=</span> ONE <span class="token1">*</span> <span class="token6">2</span><span class="token3">;</span> ``` ``` ## **新增幂运算** 加入右连接运算符\*\*\**来进行幂运算。 同时还支持简写的*\*\*=\*运算符,表示进行幂运算并赋值 ``` <pre class="calibre10">``` <span class="token4">printf</span><span class="token3">(</span><span class="token2">"2的3次方等于 %d\n"</span><span class="token3">,</span> <span class="token6">2</span> <span class="token1">*</span><span class="token1">*</span> <span class="token6">3</span><span class="token3">)</span><span class="token3">;</span><span class="token">//2的3次方等于 8</span> ``` ``` ## **新增\_\_debugInfo()魔术方法 当使用vardump打印类对象时触发** ## **扩展了use 以前可以导入命名空间的类现在还可以导入函数及常量** ``` <pre class="calibre10">``` namespace Name\Space <span class="token3">{</span> const FOO <span class="token1">=</span> <span class="token6">42</span><span class="token3">;</span> <span class="token5">function</span> <span class="token4">f</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> echo __FUNCTION__<span class="token3">.</span><span class="token2">"\n"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> namespace <span class="token3">{</span> use const Name\Space\FOO<span class="token3">;</span> use <span class="token5">function</span> Name\Space\f<span class="token3">;</span> echo FOO<span class="token3">.</span><span class="token2">"\n"</span><span class="token3">;</span><span class="token">//42</span> <span class="token4">f</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span><span class="token">//Name\Space\f</span> <span class="token3">}</span> ``` ``` # **php7新特性** php7有三种方式创建空对象 ``` <pre class="calibre10">``` $obj1 <span class="token1">=</span> <span class="token5">new</span> <span class="token4"><span class="token3">\</span>stdClass</span><span class="token3">;</span> <span class="token">// Instantiate stdClass object</span> $obj2 <span class="token1">=</span> <span class="token5">new</span> <span class="token4">class</span><span class="token3">{</span><span class="token3">}</span><span class="token3">;</span> <span class="token">// Instantiate anonymous class</span> $obj3 <span class="token1">=</span> <span class="token3">(</span>object<span class="token3">)</span><span class="token3">[</span><span class="token3">]</span><span class="token3">;</span> <span class="token">// Cast empty array to object</span> <span class="token4">var_dump</span><span class="token3">(</span>$obj1<span class="token3">)</span><span class="token3">;</span> <span class="token">// object(stdClass)#1 (0) {}</span> <span class="token4">var_dump</span><span class="token3">(</span>$obj2<span class="token3">)</span><span class="token3">;</span> <span class="token">// object(class@anonymous)#2 (0) {}</span> <span class="token4">var_dump</span><span class="token3">(</span>$obj3<span class="token3">)</span><span class="token3">;</span> <span class="token">// object(stdClass)#3 (0) {}</span> ``` ``` $obj1和$obj3类型一样但是不相等 ## **1.在use语句增加了group支持** ``` <pre class="calibre10">``` use FooLibrary\Bar\Baz\<span class="token3">{</span> ClassA<span class="token3">,</span> ClassB<span class="token3">,</span> ClassC<span class="token3">,</span> ClassD as Fizbo <span class="token3">}</span><span class="token3">;</span> ``` ``` php7.2末尾可以留,而不会报错 ``` <pre class="calibre10">``` use FooLibrary\Bar\Baz\<span class="token3">{</span> ClassA<span class="token3">,</span> ClassB<span class="token3">,</span> ClassC<span class="token3">,</span> ClassD as Fizbo<span class="token3">,</span> <span class="token3">}</span><span class="token3">;</span> ``` ``` ## **2.类型约束与标量类型声明(标量string、int、float和 bool)** 现在可在参数前加上参数类型,支持:具体类名接口名(php5.0),self(php5.0),array(php5.1),callable(php5.4),string(php7.0),int(php7.0),float(php7.0),bool(php7.0),iterable(php7.1),object(php7.2) > 特别注意 Closure类型约束的是匿名函数,匿名函数本身就是个Closure对象 > php有两种模式强制模式(默认)和严格模式 > 声明严格模式`declare(strict_types=1);`后,如果形参声明为int那么参数是其他类型比如string时就会抛出致命错误,强制模式下的话会将string转换为int而不会报错 > 由上可知php5有可以约束array 类和接口 可调用函数 self 类型,我们可以简单的认为php5类型约束是严格模式如`function foo(array $arr) {} foo(null)`会报错提示给的参数不是指定的类型,但是参数为null时还是会报这个错,解决办法是将默认参数给个null`function foo(array $arr = null) {}`这样fool(null)就不会报错了 ``` <pre class="calibre10">``` class <span class="token4">A</span><span class="token3">{</span> public $name<span class="token1">=</span><span class="token5">null</span><span class="token3">;</span> public <span class="token5">function</span> <span class="token4">demo</span><span class="token3">(</span>self $a<span class="token3">)</span><span class="token3">{</span> <span class="token4">var_dump</span><span class="token3">(</span>$a<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span><span class="token4">demo</span><span class="token3">(</span>$this<span class="token3">)</span><span class="token3">;</span> <span class="token">//$this->demo(new stdClass()); // 致命错误 A::demo() must be an instance of A</span> <span class="token3">}</span> <span class="token3">}</span> class <span class="token4">B</span> implements <span class="token4">Iterator</span><span class="token3">{</span><span class="token">//Iterator继承Traversable</span> public <span class="token5">function</span> current <span class="token3">(</span><span class="token3">)</span><span class="token3">{</span><span class="token3">}</span> <span class="token">//返回当前产生的值</span> public <span class="token5">function</span> key <span class="token3">(</span><span class="token3">)</span><span class="token3">{</span><span class="token3">}</span> <span class="token">//返回当前产生的键</span> public <span class="token5">function</span> next <span class="token3">(</span><span class="token3">)</span><span class="token3">{</span><span class="token3">}</span> <span class="token">// 生成器继续执行</span> public <span class="token5">function</span> rewind <span class="token3">(</span><span class="token3">)</span><span class="token3">{</span><span class="token3">}</span> <span class="token">//重置迭代器</span> public <span class="token5">function</span> valid <span class="token3">(</span><span class="token3">)</span><span class="token3">{</span><span class="token3">}</span> <span class="token">//检查迭代器是否被关闭</span> <span class="token3">}</span> <span class="token5">new</span> <span class="token4">A</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//字符串</span> <span class="token5">function</span> <span class="token4">demo</span><span class="token3">(</span>string $param<span class="token3">)</span><span class="token3">{</span> <span class="token4">var_dump</span><span class="token3">(</span><span class="token4">is_string</span><span class="token3">(</span>$param<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">demo</span><span class="token3">(</span><span class="token6">1</span><span class="token3">)</span><span class="token3">;</span><span class="token">//true</span> <span class="token4">demo</span><span class="token3">(</span><span class="token6">2.2</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//true</span> <span class="token">//整数</span> <span class="token5">function</span> <span class="token4">demo1</span><span class="token3">(</span>int $param<span class="token3">)</span><span class="token3">{</span> echo $param<span class="token3">;</span> <span class="token4">var_dump</span><span class="token3">(</span><span class="token4">is_integer</span><span class="token3">(</span>$param<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">demo1</span><span class="token3">(</span><span class="token2">'1.1'</span><span class="token3">)</span><span class="token3">;</span><span class="token">//1 true</span> <span class="token4">demo1</span><span class="token3">(</span><span class="token6">1.1</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//1 true</span> <span class="token">//浮点数</span> <span class="token5">function</span> <span class="token4">demo2</span><span class="token3">(</span>float $param<span class="token3">)</span><span class="token3">{</span> echo $param<span class="token3">;</span> <span class="token4">var_dump</span><span class="token3">(</span><span class="token4">is_float</span><span class="token3">(</span>$param<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">demo2</span><span class="token3">(</span><span class="token2">'1.2'</span><span class="token3">)</span><span class="token3">;</span><span class="token">//1.2 true</span> <span class="token4">demo2</span><span class="token3">(</span><span class="token6">1</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//1 true</span> <span class="token">//布尔值</span> <span class="token5">function</span> <span class="token4">demo3</span><span class="token3">(</span>bool $param<span class="token3">)</span><span class="token3">{</span> <span class="token4">var_dump</span><span class="token3">(</span>$param<span class="token3">)</span><span class="token3">;</span> <span class="token4">var_dump</span><span class="token3">(</span><span class="token4">is_bool</span><span class="token3">(</span>$param<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">demo3</span><span class="token3">(</span><span class="token2">'a'</span><span class="token3">)</span><span class="token3">;</span><span class="token">// true true</span> <span class="token4">demo3</span><span class="token3">(</span><span class="token6">3.3</span><span class="token3">)</span><span class="token3">;</span><span class="token">// true true</span> <span class="token">//数组</span> <span class="token5">function</span> <span class="token4">demo4</span><span class="token3">(</span>array $param<span class="token3">)</span><span class="token3">{</span> <span class="token4">var_dump</span><span class="token3">(</span>$param<span class="token3">)</span><span class="token3">;</span> <span class="token4">var_dump</span><span class="token3">(</span><span class="token4">is_array</span><span class="token3">(</span>$param<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">demo4</span><span class="token3">(</span><span class="token3">[</span><span class="token2">'a'</span><span class="token3">]</span><span class="token3">)</span><span class="token3">;</span><span class="token">//['a'] true</span> <span class="token">//demo4('a');//demo4() must be of the type array</span> <span class="token">//函数</span> <span class="token5">function</span> <span class="token4">demo5</span><span class="token3">(</span>callable $param<span class="token3">)</span><span class="token3">{</span> $<span class="token4">param</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">var_dump</span><span class="token3">(</span><span class="token4">is_callable</span><span class="token3">(</span>$param<span class="token3">,</span><span class="token6">true</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">demo5</span><span class="token3">(</span><span class="token5">function</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span>echo <span class="token6">111</span><span class="token3">;</span><span class="token3">}</span><span class="token3">)</span><span class="token3">;</span><span class="token">// 111 true</span> <span class="token">//对象</span> <span class="token5">function</span> <span class="token4">demo6</span><span class="token3">(</span>object $param<span class="token3">)</span><span class="token3">{</span> <span class="token4">var_dump</span><span class="token3">(</span><span class="token4">is_object</span><span class="token3">(</span>$param<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">demo6</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">A</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span><span class="token">//true</span> <span class="token">//迭代对象</span> <span class="token5">function</span> <span class="token4">demo7</span><span class="token3">(</span>iterable $param<span class="token3">)</span><span class="token3">{</span> <span class="token4">var_dump</span><span class="token3">(</span>$param <span class="token5">instanceof</span> <span class="token4">Traversable</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//var_dump(is_iterable($param));</span> <span class="token3">}</span> <span class="token4">demo7</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">B</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span><span class="token">//true</span> <span class="token4">demo7</span><span class="token3">(</span><span class="token3">[</span><span class="token6">1</span><span class="token3">,</span><span class="token6">2</span><span class="token3">]</span><span class="token3">)</span><span class="token3">;</span><span class="token">//false php7.2以前致命错误demo6() must be an instance of iterable</span> <span class="token">//具体类名或接口名</span> <span class="token5">function</span> <span class="token4">demo9</span><span class="token3">(</span>Exception $param<span class="token3">)</span><span class="token3">{</span> <span class="token4">print_r</span><span class="token3">(</span>$param<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//demo9(new Exception('哈哈'));</span> <span class="token">//demo9(new A());//致命错误 demo3() must be an instance of Exception,</span> ``` ``` ## **3.返回值类型声明** 可用的类型与参数声明中可用的类型相同。即支持:具体类名接口名(php5.0),self(php5.0),array(php5.1),callable(php5.4),string(php7.0),int(php7.0),float(php7.0),bool(php7.0),iterable(php7.1),void(php7.1),object(php7.2) > 注意指定类型后不能返回null,php7.1在类型前加?可解决此问题 ``` <pre class="calibre10">``` <span class="token5">function</span> <span class="token4">demo</span><span class="token3">(</span>$param<span class="token3">)</span><span class="token3">:</span>int<span class="token3">{</span> <span class="token5">return</span> $param<span class="token3">;</span> <span class="token3">}</span> <span class="token4">demo</span><span class="token3">(</span><span class="token5">null</span><span class="token3">)</span><span class="token3">;</span><span class="token">//7.0致命错误</span> <span class="token5">function</span> <span class="token4">demo1</span><span class="token3">(</span>$param<span class="token3">)</span><span class="token3">:</span><span class="token1">?</span>int<span class="token3">{</span> <span class="token5">return</span> $param<span class="token3">;</span> <span class="token3">}</span> <span class="token4">demo1</span><span class="token3">(</span><span class="token5">null</span><span class="token3">)</span><span class="token3">;</span><span class="token">//php7.1类型前加上?就能接受及返回null</span> <span class="token5">function</span> <span class="token4">demo</span><span class="token3">(</span><span class="token1">?</span>int $param<span class="token3">)</span><span class="token3">:</span><span class="token1">?</span>int<span class="token3">{</span> <span class="token5">return</span> $param<span class="token3">;</span> <span class="token3">}</span> <span class="token4">demo</span><span class="token3">(</span><span class="token5">null</span><span class="token3">)</span><span class="token3">;</span><span class="token">//php7.1类型前加上?就能接受及返回null</span> ``` ``` ## **4.三元运算新增null合并运算符??** 当第一个表达式的值不存在或者为null时返回第二个表达式的值,否则返回第一个表达式的值,详情参看其他--三元运算章节 ``` <pre class="calibre10">``` $username <span class="token1">=</span> $_GET<span class="token3">[</span><span class="token2">'user'</span><span class="token3">]</span> <span class="token1">?</span><span class="token1">?</span> <span class="token2">'nobody'</span><span class="token3">;</span> echo $username<span class="token3">;</span><span class="token">//nobody</span> ``` ``` ## **5.太空船操作符<=>(组合比较符)** 太空船操作符用于比较两个表达式。当$a小于、等于或大于$b时它分别返回-1、0或1。 比较的原则是沿用 PHP 的常规比较规则进行的。 ``` <pre class="calibre10">``` <span class="token">// 整数</span> echo <span class="token6">1</span> <span class="token1"><=</span><span class="token1">></span> <span class="token6">1</span><span class="token3">;</span> <span class="token">// 0</span> echo <span class="token6">1</span> <span class="token1"><=</span><span class="token1">></span> <span class="token6">2</span><span class="token3">;</span> <span class="token">// -1</span> echo <span class="token6">2</span> <span class="token1"><=</span><span class="token1">></span> <span class="token6">1</span><span class="token3">;</span> <span class="token">// 1</span> <span class="token">// 浮点数</span> echo <span class="token6">1.5</span> <span class="token1"><=</span><span class="token1">></span> <span class="token6">1.5</span><span class="token3">;</span> <span class="token">// 0</span> echo <span class="token6">1.5</span> <span class="token1"><=</span><span class="token1">></span> <span class="token6">2.5</span><span class="token3">;</span> <span class="token">// -1</span> echo <span class="token6">2.5</span> <span class="token1"><=</span><span class="token1">></span> <span class="token6">1.5</span><span class="token3">;</span> <span class="token">// 1</span> <span class="token">// 字符串</span> echo <span class="token2">"a"</span> <span class="token1"><=</span><span class="token1">></span> <span class="token2">"a"</span><span class="token3">;</span> <span class="token">// 0</span> echo <span class="token2">"a"</span> <span class="token1"><=</span><span class="token1">></span> <span class="token2">"b"</span><span class="token3">;</span> <span class="token">// -1</span> echo <span class="token2">"b"</span> <span class="token1"><=</span><span class="token1">></span> <span class="token2">"a"</span><span class="token3">;</span> <span class="token">// 1</span> ``` ``` ## **6.define支持定义数组** 自从PHP5.6后,使用const数组也能被定义为常量,define在PHP7中被实现 ## **7.支持[匿名类](https://www.php.net/manual/zh/language.oop5.anonymous.php)** 现在支持通过new class来实例化一个匿名类,这可以用来替代一些“用后即焚”的完整类定义 ``` <pre class="calibre10">``` interface <span class="token4">Logger</span> <span class="token3">{</span> public <span class="token5">function</span> <span class="token4">log</span><span class="token3">(</span>string $msg<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> class <span class="token4">Application</span> <span class="token3">{</span> private $logger<span class="token3">;</span> public <span class="token5">function</span> <span class="token4">getLogger</span><span class="token3">(</span><span class="token3">)</span><span class="token3">:</span> Logger <span class="token3">{</span> <span class="token5">return</span> $this<span class="token1">-</span><span class="token1">></span>logger<span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">setLogger</span><span class="token3">(</span>Logger $logger<span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>logger <span class="token1">=</span> $logger<span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> $app <span class="token1">=</span> <span class="token5">new</span> <span class="token4">Application</span><span class="token3">;</span> $app<span class="token1">-</span><span class="token1">></span><span class="token4">setLogger</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">class</span> implements <span class="token4">Logger</span> <span class="token3">{</span> public <span class="token5">function</span> <span class="token4">log</span><span class="token3">(</span>string $msg<span class="token3">)</span> <span class="token3">{</span> echo $msg<span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">var_dump</span><span class="token3">(</span>$app<span class="token1">-</span><span class="token1">></span><span class="token4">getLogger</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span><span class="token">//object(class@anonymous)#2 (0) {}</span> ``` ``` ## [**8.Unicode字符编码表**](https://www.cnblogs.com/chris-oil/p/8677309.html) 中日韩统一表意文字(CJK Unified Ideographs),外加一些特殊的字符;用 \[ \\u2E80-\\uFE4F\] ``` <pre class="calibre10">``` echo <span class="token2">'\u{2E80}'</span><span class="token3">;</span><span class="token">//\u{2E80} 必须双引号</span> echo <span class="token2">"\u{2E80}"</span><span class="token3">;</span><span class="token">//⺀</span> ``` ``` ## **9.增强之前的[assert()](https://www.php.net/manual/zh/function.assert.php)的方法** 简单但却最精确的定义一个*表达式*的方式就是“任何有值的东西” 早期assert是一个函数,php7是一个语法结构(在php语言中是用来判断一个表达式是否成立。返回true or false;) 老版本的API出于兼容目的将继续被维护,assert()现在是一个语言结构, 断言在PHP 5,这必须是一个字符串或者一个布尔计算测试。在PHP 7中,这也可以是**返回值的任何表达式**,该值将被执行,其结果用于指示断言是否成功或失败 **php7新增的的ini配置如下:** **zend.assertions** 1:生成并执行代码(开发模式) 0:生成代码,但在运行时绕过它 -1:不生成代码(生产模式) > **zend.assertions=1** ## **assert.exception** //1:当断言失败时抛出,方法是抛出作为异常提供的对象,或者在没有提供异常时抛出一个新的AssertionError对象 //0:使用或生成一个Throwable,如前所述,但只生成一个基于该对象的警告,而不是抛出它(兼容PHP 5行为) > **assert.exception=0** ``` <pre class="calibre10">``` <span class="token4">assert</span><span class="token3">(</span><span class="token6">true</span> <span class="token1">==</span> <span class="token6">false</span><span class="token3">)</span><span class="token3">;</span> echo <span class="token2">'Hi!'</span><span class="token3">;</span> zend<span class="token3">.</span>assertions<span class="token1">=</span><span class="token6">0</span>时输出: Hi<span class="token1">!</span> zend<span class="token3">.</span>assertions<span class="token1">=</span><span class="token6">1</span>并且assert<span class="token3">.</span>exception<span class="token1">=</span><span class="token6">0</span>时输出: Warning<span class="token3">:</span> <span class="token4">assert</span><span class="token3">(</span><span class="token3">)</span><span class="token3">:</span> <span class="token4">assert</span><span class="token3">(</span><span class="token6">true</span> <span class="token1">==</span> <span class="token6">false</span><span class="token3">)</span> failed <span class="token5">in</span> <span class="token1">-</span> on line <span class="token6">2</span> Hi<span class="token1">!</span> zend<span class="token3">.</span>assertions<span class="token1">=</span><span class="token6">1</span>并且assert<span class="token3">.</span>exception<span class="token1">=</span><span class="token6">1</span>时输出: Fatal error<span class="token3">:</span> Uncaught AssertionError<span class="token3">:</span> <span class="token4">assert</span><span class="token3">(</span><span class="token6">true</span> <span class="token1">==</span> <span class="token6">false</span><span class="token3">)</span> <span class="token5">in</span> <span class="token1">-</span><span class="token3">:</span><span class="token6">2</span> Stack trace<span class="token3">:</span> #<span class="token6">0</span> <span class="token1">-</span><span class="token3">(</span><span class="token6">2</span><span class="token3">)</span><span class="token3">:</span> <span class="token4">assert</span><span class="token3">(</span><span class="token6">false</span><span class="token3">,</span> <span class="token2">'assert(true == ...'</span><span class="token3">)</span> #<span class="token6">1</span> <span class="token3">{</span>main<span class="token3">}</span> thrown <span class="token5">in</span> <span class="token1">-</span> on line <span class="token6">2</span> ``` ``` ## **10.为unserialize()提供过滤** ``` <pre class="calibre10">``` <span class="token">//将所有对象分为__PHP_Incomplete_Class对象</span> $data <span class="token1">=</span> <span class="token4">unserialize</span><span class="token3">(</span>$foo<span class="token3">,</span> <span class="token3">[</span><span class="token2">"allowed_classes"</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">false</span><span class="token3">]</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//将所有对象分为__PHP_Incomplete_Class 对象 除了ClassName1和ClassName2</span> $data <span class="token1">=</span> <span class="token4">unserialize</span><span class="token3">(</span>$foo<span class="token3">,</span> <span class="token3">[</span><span class="token2">"allowed_classes"</span> <span class="token1">=</span><span class="token1">></span> <span class="token3">[</span><span class="token2">"ClassName1"</span><span class="token3">,</span> <span class="token2">"ClassName2"</span><span class="token3">]</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//默认行为,和 unserialize($foo)相同</span> $data <span class="token1">=</span> <span class="token4">unserialize</span><span class="token3">(</span>$foo<span class="token3">,</span> <span class="token3">[</span><span class="token2">"allowed_classes"</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">true</span><span class="token3">]</span><span class="token3">)</span><span class="token3">;</span> ``` ``` ## **11.增加Closure::call支持** Closure::call将一个闭包函数动态绑定到一个新的对象实例并调用执行该函数, ``` <pre class="calibre10">``` class <span class="token4">Value</span> <span class="token3">{</span> protected $value<span class="token3">;</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span>$value<span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>value <span class="token1">=</span> $value<span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">getValue</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> $this<span class="token1">-</span><span class="token1">></span>value<span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> $three <span class="token1">=</span> <span class="token5">new</span> <span class="token4">Value</span><span class="token3">(</span><span class="token6">3</span><span class="token3">)</span><span class="token3">;</span> $four <span class="token1">=</span> <span class="token5">new</span> <span class="token4">Value</span><span class="token3">(</span><span class="token6">4</span><span class="token3">)</span><span class="token3">;</span> $closure <span class="token1">=</span> <span class="token5">function</span> <span class="token3">(</span>$delta<span class="token3">)</span> <span class="token3">{</span> <span class="token4">var_dump</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span><span class="token4">getValue</span><span class="token3">(</span><span class="token3">)</span> <span class="token1">+</span> $delta<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span><span class="token3">;</span> $closure<span class="token1">-</span><span class="token1">></span><span class="token4">call</span><span class="token3">(</span>$three<span class="token3">,</span> <span class="token6">4</span><span class="token3">)</span><span class="token3">;</span> $closure<span class="token1">-</span><span class="token1">></span><span class="token4">call</span><span class="token3">(</span>$four<span class="token3">,</span> <span class="token6">4</span><span class="token3">)</span><span class="token3">;</span> <span class="token">// outputs int(7),int(8)</span> ``` ``` ``` <pre class="calibre10">``` class <span class="token4">Test</span> <span class="token3">{</span> public $name <span class="token1">=</span> <span class="token2">"lixuan"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//PHP7和PHP5.6都可以</span> $getNameFunc <span class="token1">=</span> <span class="token5">function</span> <span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> $this<span class="token1">-</span><span class="token1">></span>name<span class="token3">;</span> <span class="token3">}</span><span class="token3">;</span> $name <span class="token1">=</span> $getNameFunc<span class="token1">-</span><span class="token1">></span><span class="token4">bindTo</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">Test</span><span class="token3">,</span> <span class="token2">'Test'</span><span class="token3">)</span><span class="token3">;</span> echo $<span class="token4">name</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//PHP7可以,PHP5.6报错</span> $getX <span class="token1">=</span> <span class="token5">function</span> <span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> $this<span class="token1">-</span><span class="token1">></span>name<span class="token3">;</span> <span class="token3">}</span><span class="token3">;</span> echo $getX<span class="token1">-</span><span class="token1">></span><span class="token4">call</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">Test</span><span class="token3">)</span><span class="token3">;</span> ``` ``` ## **12.新增整数除法函数** intdiv 接收两个参数作为被除数和除数,返回他们相除结果的整数部分。 ``` <pre class="calibre10">``` <span class="token">// 7/2=3余1 值保留整数部分3</span> <span class="token4">var_dump</span><span class="token3">(</span><span class="token4">intdiv</span><span class="token3">(</span><span class="token6">7</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span><span class="token">//int(3)</span> ``` ``` ## **13.新增加的 IntlChar 类** 旨在暴露出更多的 ICU 功能。这个类自身定义了许多静态方法用于操作多字符集的 unicode 字符。Intl是Pecl扩展,使用前需要编译进PHP中,也可apt-get/yum/port install php5-intl ``` <pre class="calibre10">``` <span class="token4">printf</span><span class="token3">(</span><span class="token2">'%x'</span><span class="token3">,</span> IntlChar<span class="token3">:</span><span class="token3">:</span>CODEPOINT_MAX<span class="token3">)</span><span class="token3">;</span> echo IntlChar<span class="token3">:</span><span class="token3">:</span><span class="token4">charName</span><span class="token3">(</span><span class="token2">'@'</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">var_dump</span><span class="token3">(</span>IntlChar<span class="token3">:</span><span class="token3">:</span><span class="token4">ispunct</span><span class="token3">(</span><span class="token2">'!'</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> ``` ``` 以上例程会输出: 10ffff COMMERCIAL AT bool(true) CSPRNG ## **14.新增两个跨平台函数:** 可用于生成salt、密钥或初始化向量 兼容windows,linux或者其他大多数平台,如果不兼容抛出异常 **random\_bytes** — 生成加密安全的伪随机字节 ``` <pre class="calibre10">``` <span class="token">//随机字节的长度设置为5</span> $bytes <span class="token1">=</span> <span class="token4">random_bytes</span><span class="token3">(</span><span class="token6">5</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">print_r</span><span class="token3">(</span>$bytes<span class="token3">)</span><span class="token3">;</span> <span class="token">//转换为十六进制值</span> $hexadecimal <span class="token1">=</span> <span class="token4">bin2hex</span><span class="token3">(</span>$bytes<span class="token3">)</span><span class="token3">;</span> <span class="token4">var_dump</span><span class="token3">(</span>$hexadecimal<span class="token3">)</span><span class="token3">;</span><span class="token">//类似8c7c0481d6的字符串</span> ``` ``` 使用下面的函数来创建随机的令牌,并且还从令牌中创建了一个salt。我在我的应用程序中使用它来防止CSRF攻击 ``` <pre class="calibre10">``` <span class="token5">function</span> <span class="token4">RandomToken</span><span class="token3">(</span>$length <span class="token1">=</span> <span class="token6">32</span><span class="token3">)</span><span class="token3">{</span> <span class="token5">if</span><span class="token3">(</span><span class="token1">!</span><span class="token4">isset</span><span class="token3">(</span>$length<span class="token3">)</span> <span class="token1">||</span> <span class="token4">intval</span><span class="token3">(</span>$length<span class="token3">)</span> <span class="token1"><=</span> <span class="token6">8</span> <span class="token3">)</span><span class="token3">{</span> $length <span class="token1">=</span> <span class="token6">32</span><span class="token3">;</span> <span class="token3">}</span> <span class="token5">if</span> <span class="token3">(</span><span class="token4">function_exists</span><span class="token3">(</span><span class="token2">'random_bytes'</span><span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> <span class="token4">bin2hex</span><span class="token3">(</span><span class="token4">random_bytes</span><span class="token3">(</span>$length<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token5">if</span> <span class="token3">(</span><span class="token4">function_exists</span><span class="token3">(</span><span class="token2">'mcrypt_create_iv'</span><span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> <span class="token4">bin2hex</span><span class="token3">(</span><span class="token4">mcrypt_create_iv</span><span class="token3">(</span>$length<span class="token3">,</span> MCRYPT_DEV_URANDOM<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token5">if</span> <span class="token3">(</span><span class="token4">function_exists</span><span class="token3">(</span><span class="token2">'openssl_random_pseudo_bytes'</span><span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> <span class="token4">bin2hex</span><span class="token3">(</span><span class="token4">openssl_random_pseudo_bytes</span><span class="token3">(</span>$length<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token5">function</span> <span class="token4">Salt</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> <span class="token5">return</span> <span class="token4">substr</span><span class="token3">(</span><span class="token4">strtr</span><span class="token3">(</span><span class="token4">base64_encode</span><span class="token3">(</span><span class="token4">hex2bin</span><span class="token3">(</span><span class="token4">RandomToken</span><span class="token3">(</span><span class="token6">32</span><span class="token3">)</span><span class="token3">)</span><span class="token3">)</span><span class="token3">,</span> <span class="token2">'+'</span><span class="token3">,</span> <span class="token2">'.'</span><span class="token3">)</span><span class="token3">,</span> <span class="token6">0</span><span class="token3">,</span> <span class="token6">44</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> echo <span class="token3">(</span><span class="token4">RandomToken</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> echo <span class="token2">'<br>'</span><span class="token3">;</span> echo <span class="token4">Salt</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token">/* 调试上面的几个函数 */</span> <span class="token5">function</span> <span class="token4">RandomTokenDebug</span><span class="token3">(</span>$length <span class="token1">=</span> <span class="token6">32</span><span class="token3">)</span><span class="token3">{</span> <span class="token5">if</span><span class="token3">(</span><span class="token1">!</span><span class="token4">isset</span><span class="token3">(</span>$length<span class="token3">)</span> <span class="token1">||</span> <span class="token4">intval</span><span class="token3">(</span>$length<span class="token3">)</span> <span class="token1"><=</span> <span class="token6">8</span> <span class="token3">)</span><span class="token3">{</span> $length <span class="token1">=</span> <span class="token6">32</span><span class="token3">;</span> <span class="token3">}</span> $randoms <span class="token1">=</span> <span class="token4">array</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token5">if</span> <span class="token3">(</span><span class="token4">function_exists</span><span class="token3">(</span><span class="token2">'random_bytes'</span><span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> $randoms<span class="token3">[</span><span class="token2">'random_bytes'</span><span class="token3">]</span> <span class="token1">=</span> <span class="token4">bin2hex</span><span class="token3">(</span><span class="token4">random_bytes</span><span class="token3">(</span>$length<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token5">if</span> <span class="token3">(</span><span class="token4">function_exists</span><span class="token3">(</span><span class="token2">'mcrypt_create_iv'</span><span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> $randoms<span class="token3">[</span><span class="token2">'mcrypt_create_iv'</span><span class="token3">]</span> <span class="token1">=</span> <span class="token4">bin2hex</span><span class="token3">(</span><span class="token4">mcrypt_create_iv</span><span class="token3">(</span>$length<span class="token3">,</span> MCRYPT_DEV_URANDOM<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token5">if</span> <span class="token3">(</span><span class="token4">function_exists</span><span class="token3">(</span><span class="token2">'openssl_random_pseudo_bytes'</span><span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> $randoms<span class="token3">[</span><span class="token2">'openssl_random_pseudo_bytes'</span><span class="token3">]</span> <span class="token1">=</span> <span class="token4">bin2hex</span><span class="token3">(</span><span class="token4">openssl_random_pseudo_bytes</span><span class="token3">(</span>$length<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token5">return</span> $randoms<span class="token3">;</span> <span class="token3">}</span> echo <span class="token2">'<br>'</span><span class="token3">;</span> print_r <span class="token3">(</span><span class="token4">RandomTokenDebug</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> ``` ``` **random\_int**(int`$min`,int`$max`) :int —生成加密安全的伪随机整数 生成适合在非常重要的公正的结果情况下使用的加密随机整数,例如在扑克游戏中洗牌时 ``` <pre class="calibre10">``` <span class="token4">var_dump</span><span class="token3">(</span><span class="token4">random_int</span><span class="token3">(</span><span class="token6">100</span><span class="token3">,</span> <span class="token6">999</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span><span class="token">//int(248)</span> <span class="token4">var_dump</span><span class="token3">(</span><span class="token4">random_int</span><span class="token3">(</span><span class="token1">-</span><span class="token6">1000</span><span class="token3">,</span> <span class="token6">0</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span><span class="token">//int(-898)</span> ``` ``` ## **15.新增preg\_replace\_callback\_array()函数,比preg\_replace\_callback()函数简洁** 在 PHP 7 之前,当使用 preg\_replace\_callback() 函数的时候, 由于针对每个正则表达式都要执行回调函数,可能导致过多的分支代码。 而使用新加的 preg\_replace\_callback\_array() 函数, 可以使得代码更加简洁。 现在,可以使用一个关联数组来对每个正则表达式注册回调函数, 正则表达式本身作为关联数组的键, 而对应的回调函数就是关联数组的值。 ## **16.session\_start()可以接受一个array作为参数** 现在,session\_start()函数可以接收一个数组作为参数,可以覆盖php.ini中session的配置项。 比如,把cache\_limiter设置为私有的,同时在阅读完session后立即关闭 ``` <pre class="calibre10">``` <span class="token4">session_start</span><span class="token3">(</span><span class="token3">[</span><span class="token2">'cache_limiter'</span> <span class="token1">=</span><span class="token1">></span> <span class="token2">'private'</span><span class="token3">,</span> <span class="token2">'read_and_close'</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">true</span><span class="token3">,</span> <span class="token3">]</span><span class="token3">)</span><span class="token3">;</span> ``` ``` ## **17.生成器中引入其他生成器** 在生成器中可以引入另一个或几个生成器,只需要写yield from functionName1 ``` <pre class="calibre10">``` <span class="token5">function</span> <span class="token4">generator1</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> yield <span class="token6">1</span><span class="token3">;</span> yield <span class="token6">2</span><span class="token3">;</span> yield from <span class="token4">generator2</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> yield from <span class="token4">generator3</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token5">function</span> <span class="token4">generator2</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> yield <span class="token6">3</span><span class="token3">;</span> yield <span class="token6">4</span><span class="token3">;</span> <span class="token3">}</span> <span class="token5">function</span> <span class="token4">generator3</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> yield <span class="token6">5</span><span class="token3">;</span> yield <span class="token6">6</span><span class="token3">;</span> <span class="token3">}</span> foreach <span class="token3">(</span><span class="token4">generator1</span><span class="token3">(</span><span class="token3">)</span> as $val<span class="token3">)</span> <span class="token3">{</span> echo $val<span class="token3">,</span> <span class="token2">" "</span><span class="token3">;</span> <span class="token3">}</span> ``` ``` ## **18.生成器可以返回表达式** 生成器(读取超大文件很有用,节约内存) 它允许在生成器函数中通过使用 return 语法来返回一个表达式 (但是不允许返回引用值), 可以通过调用 Generator::getReturn() 方法来获取生成器的返回值, 但是这个方法只能在生成器完成产生工作以后调用一次 ``` <pre class="calibre10">``` $gen <span class="token1">=</span> <span class="token3">(</span><span class="token5">function</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> yield <span class="token6">1</span><span class="token3">;</span> yield <span class="token6">2</span><span class="token3">;</span> <span class="token5">return</span> <span class="token6">3</span><span class="token3">;</span> <span class="token3">}</span><span class="token3">)</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> foreach <span class="token3">(</span>$gen as $val<span class="token3">)</span> <span class="token3">{</span> echo $val<span class="token3">,</span> PHP_EOL<span class="token3">;</span><span class="token">// 1 2</span> <span class="token3">}</span> <span class="token">//首先执行函数 该函数遇到yield停止并将该yied的值发送给foreach</span> echo $gen<span class="token1">-</span><span class="token1">></span><span class="token4">getReturn</span><span class="token3">(</span><span class="token3">)</span><span class="token3">,</span> PHP_EOL<span class="token3">;</span><span class="token">//3</span> 结果: <span class="token6">1</span> <span class="token6">2</span> <span class="token6">3</span> ``` ``` php全局保留字可以声明使用 ``` <pre class="calibre10">``` class <span class="token4">View</span> <span class="token3">{</span> public <span class="token5">function</span> <span class="token4">include</span><span class="token3">(</span>View $view<span class="token3">)</span> <span class="token3">{</span> <span class="token">//...</span> <span class="token">//include关键字可以当普通字符串关键字一样被使[其他](%E5%85%B6%E4%BB%96.md)用</span> <span class="token3">}</span> <span class="token3">}</span> ``` ``` 允许在克隆表达式上访问对象成员,例如:*(clone $foo)->bar()*。 # **php7.1新特性** ## **参数和返回类型支持null,前提是在类型前加?** ``` <pre class="calibre10">``` <span class="token5">function</span> <span class="token4">test1</span><span class="token3">(</span><span class="token1">?</span>string $name<span class="token3">)</span> <span class="token3">{</span> <span class="token4">var_dump</span><span class="token3">(</span>$name<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//在默认非严格模式下,标量string、int、float和 bool 之间会强制转化,与php7相比php7.1可接受null</span> <span class="token4">test1</span><span class="token3">(</span><span class="token2">'dash'</span><span class="token3">)</span><span class="token3">;</span><span class="token">//'dash'</span> <span class="token4">test1</span><span class="token3">(</span><span class="token5">null</span><span class="token3">)</span><span class="token3">;</span><span class="token">//NULL</span> <span class="token4">test1</span><span class="token3">(</span><span class="token6">30</span><span class="token3">)</span><span class="token3">;</span><span class="token">//'30'</span> <span class="token4">test1</span><span class="token3">(</span><span class="token6">30.1</span><span class="token3">)</span><span class="token3">;</span><span class="token">//'30.1'</span> <span class="token4">test1</span><span class="token3">(</span><span class="token6">true</span><span class="token3">)</span><span class="token3">;</span><span class="token">//'1'</span> <span class="token4">test1</span><span class="token3">(</span><span class="token3">[</span><span class="token6">1</span><span class="token3">,</span><span class="token6">2</span><span class="token3">]</span><span class="token3">)</span><span class="token3">;</span><span class="token">//致命错误</span> <span class="token4">test1</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">stdClass</span><span class="token3">)</span><span class="token3">;</span><span class="token">//致命错误</span> <span class="token5">function</span> <span class="token4">test1</span><span class="token3">(</span>$name<span class="token3">)</span><span class="token3">:</span><span class="token1">?</span>string <span class="token3">{</span> <span class="token5">return</span> $name<span class="token3">;</span> <span class="token3">}</span> echo <span class="token4">gettype</span><span class="token3">(</span><span class="token4">test1</span><span class="token3">(</span><span class="token2">'dash'</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span><span class="token">//string</span> echo <span class="token4">gettype</span><span class="token3">(</span><span class="token4">test1</span><span class="token3">(</span><span class="token5">null</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span><span class="token">//NULL</span> echo <span class="token4">gettype</span><span class="token3">(</span><span class="token4">test1</span><span class="token3">(</span><span class="token6">30</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span><span class="token">//string</span> echo <span class="token4">gettype</span><span class="token3">(</span><span class="token4">test1</span><span class="token3">(</span><span class="token6">30.1</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span><span class="token">//string</span> echo <span class="token4">gettype</span><span class="token3">(</span><span class="token4">test1</span><span class="token3">(</span><span class="token6">true</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span><span class="token">//string</span> <span class="token4">test1</span><span class="token3">(</span><span class="token3">[</span><span class="token6">1</span><span class="token3">,</span><span class="token6">2</span><span class="token3">]</span><span class="token3">)</span><span class="token3">;</span><span class="token">//致命错误</span> <span class="token4">test1</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">stdClass</span><span class="token3">)</span><span class="token3">;</span><span class="token">//致命错误</span> ``` ``` ## **php7.1返回类型新增void** ``` <pre class="calibre10">``` <span class="token5">function</span> <span class="token4">test</span><span class="token3">(</span><span class="token3">)</span><span class="token3">:</span> void <span class="token3">{</span> <span class="token5">return</span> <span class="token2">'hello'</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">test</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span><span class="token">//致命错误</span> <span class="token5">function</span> <span class="token4">test1</span><span class="token3">(</span><span class="token3">)</span><span class="token3">:</span> void <span class="token3">{</span> <span class="token5">return</span> <span class="token5">null</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">test1</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span><span class="token">//致命错误</span> <span class="token5">function</span> <span class="token4">test2</span><span class="token3">(</span><span class="token3">)</span><span class="token3">:</span> void <span class="token3">{</span> <span class="token5">return</span> <span class="token2">''</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">test2</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span><span class="token">//致命错误</span> <span class="token5">function</span> <span class="token4">test3</span><span class="token3">(</span><span class="token3">)</span><span class="token3">:</span> void <span class="token3">{</span> <span class="token5">return</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">test3</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span><span class="token">//正常</span> <span class="token5">function</span> <span class="token4">test4</span><span class="token3">(</span><span class="token3">)</span><span class="token3">:</span> void <span class="token3">{</span> <span class="token">//无返回值</span> <span class="token3">}</span> <span class="token4">test4</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span><span class="token">//正常</span> ``` ``` ## **短数组语法(*\[\]*)现在作为list()语法的一个备选项,可以用于将数组的值赋给一些变量(包括在*foreach*中)** ``` <pre class="calibre10">``` $data <span class="token1">=</span> <span class="token3">[</span> <span class="token3">[</span><span class="token6">1</span><span class="token3">,</span> <span class="token2">'Tom'</span><span class="token3">]</span><span class="token3">,</span> <span class="token3">[</span><span class="token6">2</span><span class="token3">,</span> <span class="token2">'Fred'</span><span class="token3">]</span><span class="token3">,</span> <span class="token3">]</span><span class="token3">;</span> <span class="token">//php之前支持格式</span> <span class="token4">list</span><span class="token3">(</span>$id1<span class="token3">,</span> $name1<span class="token3">)</span> <span class="token1">=</span> $data<span class="token3">[</span><span class="token6">0</span><span class="token3">]</span><span class="token3">;</span> foreach <span class="token3">(</span>$data as <span class="token4">list</span><span class="token3">(</span>$id<span class="token3">,</span> $name<span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> <span class="token">// logic here with $id and $name</span> <span class="token3">}</span> <span class="token">//php7新增的短数组[]格式</span> <span class="token3">[</span>$id1<span class="token3">,</span> $name1<span class="token3">]</span> <span class="token1">=</span> $data<span class="token3">[</span><span class="token6">0</span><span class="token3">]</span><span class="token3">;</span> foreach <span class="token3">(</span>$data as <span class="token3">[</span>$id<span class="token3">,</span> $name<span class="token3">]</span><span class="token3">)</span> <span class="token3">{</span> <span class="token">// logic here with $id and $name</span> <span class="token3">}</span> ``` ``` PHP 5 里,list() 从最右边的参数开始赋值; PHP 7 里,list() 从最左边的参数开始赋值 ``` <pre class="calibre10">``` $info <span class="token1">=</span> <span class="token4">array</span><span class="token3">(</span><span class="token2">'coffee'</span><span class="token3">,</span> <span class="token2">'brown'</span><span class="token3">,</span> <span class="token2">'caffeine'</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">list</span><span class="token3">(</span>$a<span class="token3">[</span><span class="token6">0</span><span class="token3">]</span><span class="token3">,</span> $a<span class="token3">[</span><span class="token6">1</span><span class="token3">]</span><span class="token3">,</span> $a<span class="token3">[</span><span class="token6">2</span><span class="token3">]</span><span class="token3">)</span> <span class="token1">=</span> $info<span class="token3">;</span> <span class="token4">print_r</span><span class="token3">(</span>$a<span class="token3">)</span><span class="token3">;</span> php5输出<span class="token3">:</span><span class="token3">[</span><span class="token6">2</span><span class="token1">=</span><span class="token1">></span><span class="token2">'caffeine'</span><span class="token3">,</span><span class="token6">1</span><span class="token1">=</span><span class="token1">></span><span class="token2">'brown'</span><span class="token3">,</span><span class="token6">0</span><span class="token1">=</span><span class="token1">></span><span class="token2">'coffee'</span><span class="token3">]</span> php7输出<span class="token3">:</span><span class="token3">[</span><span class="token6">0</span><span class="token1">=</span><span class="token1">></span><span class="token2">'coffee'</span><span class="token3">,</span><span class="token6">1</span><span class="token1">=</span><span class="token1">></span><span class="token2">'brown'</span><span class="token3">,</span><span class="token6">2</span><span class="token1">=</span><span class="token1">></span><span class="token2">'caffeine'</span><span class="token3">]</span> ``` ``` 在 PHP 7.1.0 之前的版本,list() 仅能用于数字索引的数组,并假定数字索引从 0 开始 从 PHP 7.1.0 开始,list() 可以包含显式的键,可赋值到任意表达式。 可以混合使用数字和字符串键。但是不能混合有键和无键不能混用 ``` <pre class="calibre10">``` $data <span class="token1">=</span> <span class="token3">[</span> <span class="token3">[</span><span class="token2">"id"</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">1</span><span class="token3">,</span> <span class="token2">"name"</span> <span class="token1">=</span><span class="token1">></span> <span class="token2">'Tom'</span><span class="token3">]</span><span class="token3">,</span> <span class="token3">[</span><span class="token2">"id"</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">2</span><span class="token3">,</span> <span class="token2">"name"</span> <span class="token1">=</span><span class="token1">></span> <span class="token2">'Fred'</span><span class="token3">]</span><span class="token3">,</span> <span class="token3">]</span><span class="token3">;</span> foreach <span class="token3">(</span>$data as <span class="token3">[</span><span class="token2">"id"</span> <span class="token1">=</span><span class="token1">></span> $id<span class="token3">,</span> <span class="token2">"name"</span> <span class="token1">=</span><span class="token1">></span> $name<span class="token3">]</span><span class="token3">)</span> <span class="token3">{</span> echo <span class="token2">"id: $id, name: $name\n"</span><span class="token3">;</span><span class="token">//id: 1, name: Tom id: 2, name: Fred</span> <span class="token3">}</span> echo PHP_EOL<span class="token3">;</span> <span class="token4">list</span><span class="token3">(</span><span class="token6">1</span> <span class="token1">=</span><span class="token1">></span> $second<span class="token3">,</span> <span class="token6">3</span> <span class="token1">=</span><span class="token1">></span> $fourth<span class="token3">)</span> <span class="token1">=</span> <span class="token3">[</span><span class="token6">1</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">,</span> <span class="token6">3</span><span class="token3">,</span> <span class="token6">4</span><span class="token3">]</span><span class="token3">;</span> echo $second<span class="token3">.</span>$fourth<span class="token3">.</span>PHP_EOL<span class="token3">;</span><span class="token">//2 4</span> ``` ``` ## **字符串偏移量可以为负,表示为一个从字符串结尾开始的偏移量** ``` <pre class="calibre10">``` <span class="token4">var_dump</span><span class="token3">(</span><span class="token2">"abcdef"</span><span class="token3">[</span><span class="token1">-</span><span class="token6">2</span><span class="token3">]</span><span class="token3">)</span><span class="token3">;</span><span class="token">//e</span> <span class="token">//b在abcdef首次出现的位置 从结尾倒数第5个偏移开始查找</span> echo <span class="token4">strpos</span><span class="token3">(</span><span class="token2">'abcdef'</span><span class="token3">,</span><span class="token2">'b'</span><span class="token3">,</span> <span class="token1">-</span><span class="token6">5</span><span class="token3">)</span><span class="token3">;</span><span class="token">//1</span> a b c d e f <span class="token6">0</span> <span class="token6">1</span> <span class="token6">2</span> <span class="token6">3</span> <span class="token6">4</span> <span class="token6">5</span> <span class="token1">-</span><span class="token6">6</span> <span class="token1">-</span><span class="token6">5</span> <span class="token1">-</span><span class="token6">4</span> <span class="token1">-</span><span class="token6">3</span> <span class="token1">-</span><span class="token6">2</span> <span class="token1">-</span><span class="token6">1</span> ``` ``` ## **字符串负偏移在简单的变量解析语法中也支持能了** ``` <pre class="calibre10">``` $string <span class="token1">=</span> <span class="token2">'bar'</span><span class="token3">;</span> echo <span class="token2">"The last character of '$string' is '$string[-1]'.\n"</span><span class="token3">;</span><span class="token">//The last character of 'bar' is 'r'.</span> ``` ``` ## **对服务器推送的支持现在已经被加入到 CURL 扩展(v7.46)中** ``` <pre class="calibre10">``` $transfers <span class="token1">=</span> <span class="token6">1</span><span class="token3">;</span> $callback <span class="token1">=</span> <span class="token5">function</span><span class="token3">(</span>$parent_ch<span class="token3">,</span> $pushed_ch<span class="token3">,</span> array $headers<span class="token3">)</span> use <span class="token3">(</span><span class="token1">&</span>$transfers<span class="token3">)</span> <span class="token3">{</span> $transfers<span class="token1">++</span><span class="token3">;</span> <span class="token">// 增量,以跟踪并发请求的数量</span> <span class="token5">return</span> CURL_PUSH_OK<span class="token3">;</span> <span class="token3">}</span><span class="token3">;</span> $mh <span class="token1">=</span> <span class="token4">curl_multi_init</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">curl_multi_setopt</span><span class="token3">(</span>$mh<span class="token3">,</span> CURLMOPT_PIPELINING<span class="token3">,</span> CURLPIPE_MULTIPLEX<span class="token3">)</span><span class="token3">;</span> <span class="token4">curl_multi_setopt</span><span class="token3">(</span>$mh<span class="token3">,</span> CURLMOPT_PUSHFUNCTION<span class="token3">,</span> $callback<span class="token3">)</span><span class="token3">;</span> $ch <span class="token1">=</span> <span class="token4">curl_init</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">curl_setopt</span><span class="token3">(</span>$ch<span class="token3">,</span> CURLOPT_URL<span class="token3">,</span> <span class="token2">"https://localhost:8080/index.html"</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">curl_setopt</span><span class="token3">(</span>$ch<span class="token3">,</span> CURLOPT_HTTP_VERSION<span class="token3">,</span> <span class="token6">3</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">curl_setopt</span><span class="token3">(</span>$ch<span class="token3">,</span> CURLOPT_RETURNTRANSFER<span class="token3">,</span> <span class="token6">1</span><span class="token3">)</span><span class="token3">;</span> <span class="token">// 调式/局部填充</span> <span class="token">//curl_setopt($ch, CURLOPT_VERBOSE, 1); // 是否会输出curl调试信息</span> <span class="token4">curl_setopt</span><span class="token3">(</span>$ch<span class="token3">,</span> CURLOPT_SSL_VERIFYHOST<span class="token3">,</span> <span class="token6">0</span><span class="token3">)</span><span class="token3">;</span> <span class="token">// self-signed cert</span> <span class="token4">curl_setopt</span><span class="token3">(</span>$ch<span class="token3">,</span> CURLOPT_SSL_VERIFYPEER<span class="token3">,</span> <span class="token6">0</span><span class="token3">)</span><span class="token3">;</span> <span class="token">// self-signed cert</span> <span class="token4">curl_multi_add_handle</span><span class="token3">(</span>$mh<span class="token3">,</span> $ch<span class="token3">)</span><span class="token3">;</span> $active <span class="token1">=</span> <span class="token5">null</span><span class="token3">;</span> <span class="token5">do</span> <span class="token3">{</span> $status <span class="token1">=</span> <span class="token4">curl_multi_exec</span><span class="token3">(</span>$mh<span class="token3">,</span> $active<span class="token3">)</span><span class="token3">;</span> <span class="token5">do</span> <span class="token3">{</span> $info <span class="token1">=</span> <span class="token4">curl_multi_info_read</span><span class="token3">(</span>$mh<span class="token3">)</span><span class="token3">;</span> <span class="token5">if</span> <span class="token3">(</span><span class="token6">false</span> <span class="token1">!==</span> $info <span class="token1">&&</span> $info<span class="token3">[</span><span class="token2">'msg'</span><span class="token3">]</span> <span class="token1">==</span> CURLMSG_DONE<span class="token3">)</span> <span class="token3">{</span> $handle <span class="token1">=</span> $info<span class="token3">[</span><span class="token2">'handle'</span><span class="token3">]</span><span class="token3">;</span> <span class="token5">if</span> <span class="token3">(</span>$handle <span class="token1">!==</span> <span class="token5">null</span><span class="token3">)</span> <span class="token3">{</span> $transfers<span class="token1">--</span><span class="token3">;</span> <span class="token">// 减量 剩余请求</span> $out <span class="token1">=</span> <span class="token4">curl_multi_getcontent</span><span class="token3">(</span>$info<span class="token3">[</span><span class="token2">'handle'</span><span class="token3">]</span><span class="token3">)</span><span class="token3">;</span> <span class="token">// 响应体</span> <span class="token4">curl_multi_remove_handle</span><span class="token3">(</span>$mh<span class="token3">,</span> $handle<span class="token3">)</span><span class="token3">;</span> <span class="token4">curl_close</span><span class="token3">(</span>$handle<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token5">while</span> <span class="token3">(</span>$info<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token5">while</span> <span class="token3">(</span>$transfers<span class="token3">)</span><span class="token3">;</span> <span class="token4">curl_multi_close</span><span class="token3">(</span>$mh<span class="token3">)</span><span class="token3">;</span> ``` ``` ## **异步信号处理** 一个新的名为 pcntl\_async\_signals() 的方法现在被引入, 用于启用无需 ticks (这会带来很多额外的开销)的异步信号处理。 ``` <pre class="calibre10">``` <span class="token4">pcntl_async_signals</span><span class="token3">(</span><span class="token6">true</span><span class="token3">)</span><span class="token3">;</span> <span class="token">// 打开异步信号</span> <span class="token4">pcntl_signal</span><span class="token3">(</span>SIGHUP<span class="token3">,</span> <span class="token5">function</span><span class="token3">(</span>$sig<span class="token3">)</span> <span class="token3">{</span> echo <span class="token2">"SIGHUP\n"</span><span class="token3">;</span> <span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">posix_kill</span><span class="token3">(</span><span class="token4">posix_getpid</span><span class="token3">(</span><span class="token3">)</span><span class="token3">,</span> SIGHUP<span class="token3">)</span><span class="token3">;</span> 以上例程会输出: SIGHUP ``` ``` ## **新增Closure::fromCallable() 将callables转为闭包** Closure新增了一个静态方法,用于将callable快速地 转为一个Closure 对象。 ``` <pre class="calibre10">``` class <span class="token4">Test</span> <span class="token3">{</span> public <span class="token5">function</span> <span class="token4">exposeFunction</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> Closure<span class="token3">:</span><span class="token3">:</span><span class="token4">fromCallable</span><span class="token3">(</span><span class="token3">[</span>$this<span class="token3">,</span> <span class="token2">'privateFunction'</span><span class="token3">]</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> private <span class="token5">function</span> <span class="token4">privateFunction</span><span class="token3">(</span>$param<span class="token3">)</span> <span class="token3">{</span> <span class="token4">var_dump</span><span class="token3">(</span>$param<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//((new Test)->exposeFunction())('some value');</span> $privFunc <span class="token1">=</span> <span class="token3">(</span><span class="token5">new</span> <span class="token4">Test</span><span class="token3">)</span><span class="token1">-</span><span class="token1">></span><span class="token4">exposeFunction</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $<span class="token4">privFunc</span><span class="token3">(</span><span class="token2">'some value'</span><span class="token3">)</span><span class="token3">;</span><span class="token">//some value</span> ``` ``` # **php7.2新特性** ## **新的对象类型** 这种新的对象类型, object, 引进了可用于逆变(contravariant)参数输入和协变(covariant)返回任何对象类型 ``` <pre class="calibre10">``` <span class="token5">function</span> <span class="token4">test</span><span class="token3">(</span>object $obj<span class="token3">)</span> <span class="token3">:</span> object <span class="token3">{</span> <span class="token5">return</span> <span class="token5">new</span> <span class="token4">SplQueue</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">test</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">StdClass</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> ``` ``` ## **既可以通过 php.ini 也可以运行时通过 dl(string $library): bool载入一个 PHP 扩展** 在 安全模式(php5.4废除),总是无法使用 dl() 不推荐,存在安全风险 如果加载模块的功能是无效或者禁用的(既可以通过设置关闭 enable\_dl(仅对 Apache 模块版本的 PHP 有效) 设置 ``` <pre class="calibre10">``` <span class="token">// 加载一个扩展的例子,基于操作系统</span> <span class="token5">if</span> <span class="token3">(</span><span class="token1">!</span><span class="token4">extension_loaded</span><span class="token3">(</span><span class="token2">'sqlite'</span><span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span><span class="token">//检查一个扩展是否已经加载</span> <span class="token5">if</span> <span class="token3">(</span><span class="token4">strtoupper</span><span class="token3">(</span><span class="token4">substr</span><span class="token3">(</span>PHP_OS<span class="token3">,</span> <span class="token6">0</span><span class="token3">,</span> <span class="token6">3</span><span class="token3">)</span><span class="token3">)</span> <span class="token1">===</span> <span class="token2">'WIN'</span><span class="token3">)</span> <span class="token3">{</span> <span class="token4">dl</span><span class="token3">(</span><span class="token2">'php_sqlite.dll'</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token5">else</span> <span class="token3">{</span> <span class="token4">dl</span><span class="token3">(</span><span class="token2">'sqlite.so'</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">// 或者,使用常量 PHP_SHLIB_SUFFIX </span> <span class="token5">if</span> <span class="token3">(</span><span class="token1">!</span><span class="token4">extension_loaded</span><span class="token3">(</span><span class="token2">'sqlite'</span><span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> $prefix <span class="token1">=</span> <span class="token3">(</span>PHP_SHLIB_SUFFIX <span class="token1">===</span> <span class="token2">'dll'</span><span class="token3">)</span> <span class="token1">?</span> <span class="token2">'php_'</span> <span class="token3">:</span> <span class="token2">''</span><span class="token3">;</span> <span class="token4">dl</span><span class="token3">(</span>$prefix <span class="token3">.</span> <span class="token2">'sqlite.'</span> <span class="token3">.</span> PHP_SHLIB_SUFFIX<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> ``` ``` ## **允许重写抽象方法** 当一个抽象类继承于另外一个抽象类的时候,继承后的抽象类可以重写被继承的抽象类的抽象方法 ``` <pre class="calibre10">``` abstract class <span class="token4">A</span> <span class="token3">{</span> abstract <span class="token5">function</span> <span class="token4">test</span><span class="token3">(</span>string $s<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> abstract class <span class="token4">B</span> extends <span class="token4">A</span> <span class="token3">{</span> <span class="token">// 覆盖 - still maintaining contravariance for parameters and covariance for return</span> abstract <span class="token5">function</span> <span class="token4">test</span><span class="token3">(</span>$s<span class="token3">)</span> <span class="token3">:</span> int<span class="token3">;</span> <span class="token3">}</span> ``` ``` ## **重写方法和接口实现的参数类型现在可以省略** ``` <pre class="calibre10">``` interface <span class="token4">A</span> <span class="token3">{</span> public <span class="token5">function</span> <span class="token4">Test</span><span class="token3">(</span>array $input<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> class <span class="token4">B</span> implements <span class="token4">A</span> <span class="token3">{</span> public <span class="token5">function</span> <span class="token4">Test</span><span class="token3">(</span>$input<span class="token3">)</span><span class="token3">{</span><span class="token3">}</span> <span class="token">// 省略了$input的类型</span> <span class="token3">}</span> ``` ``` # **php7.3新特性** ## **更灵活的`Heredoc`和`Nowdoc`语法** ``` <pre class="calibre10">``` <span class="token">//heredoc可以解析变量,nowdoc则不能解析变量</span> $name<span class="token1">=</span><span class="token2">'dash'</span><span class="token3">;</span> <span class="token">//原heredoc</span> $str<span class="token1">=</span><span class="token1"><</span><span class="token1"><</span><span class="token1"><</span>STR 这是文本第一行 这是文本第二行<span class="token3">.</span><span class="token3">{</span>$name<span class="token3">}</span>over<span class="token1">!</span> STR<span class="token3">;</span> echo $str<span class="token3">;</span><span class="token">//这是文本第一行 这是文本第二行.dashover!</span> <span class="token">//原nowdoc</span> $str <span class="token1">=</span> <span class="token1"><</span><span class="token1"><</span><span class="token1"><</span><span class="token2">'EOD'</span> Example of string spanning multiple lines using nowdoc syntax<span class="token3">.</span><span class="token3">{</span>$name<span class="token3">}</span>over! EOD<span class="token3">;</span> echo $str<span class="token3">;</span><span class="token">//Example of string spanning multiple lines using nowdoc syntax.{$name}over!</span> <span class="token">//可以使用缩进,使用缩进时doc内容的每行都会跳过相应的缩进</span> (下例两行的缩进都被剥除了) $str<span class="token1">=</span><span class="token1"><</span><span class="token1"><</span><span class="token1"><</span>STR 这是文本第一行 <span class="token1">|</span> 这是文本第二行 STR<span class="token3">;</span> <span class="token1">|</span> STR<span class="token3">;</span> echo $str<span class="token3">;</span><span class="token">// 这是文本第一行 | 这是文本第二行 STR; |</span> 两行的缩进都被剥除了 <span class="token">//结束标记不再需要独立一行</span> $str<span class="token1">=</span><span class="token1"><</span><span class="token1"><</span><span class="token1"><</span>STR 这是文本第一行 这是文本第二行 STR<span class="token3">;</span>echo $str<span class="token3">;</span><span class="token">//这是文本第一行 这是文本第二行</span> <span class="token">//在某些情况下不用紧跟分号了</span> $data <span class="token1">=</span> <span class="token3">[</span><span class="token2">"元素"</span><span class="token3">,</span> <span class="token1"><</span><span class="token1"><</span><span class="token1"><</span>STR 这是文本第一行 这是文本第二行 STR<span class="token3">,</span> <span class="token6">42</span><span class="token3">,</span><span class="token3">]</span><span class="token3">;</span> <span class="token4">print_r</span><span class="token3">(</span>$data<span class="token3">)</span><span class="token3">;</span><span class="token">//Array ( [0] => 元素 [1] => 这是文本第一行 这是文本第二行 [2] => 42 )</span> $str<span class="token1">=</span><span class="token1"><</span><span class="token1"><</span><span class="token1"><</span>STR 这是文本第一行 这是文本第二行 STR echo $str<span class="token3">;</span><span class="token">//这中情况就会报错</span> ``` ``` ## **数组析构与list结构支持引用赋值** $v = \[10, 20\]; \[$a, &$b\] = $v;//短语法等同list($a, &$b)=$v; $b += 10; var\_dump($v, $a, $b);//array(2) { \[0\]=> int(10) \[1\]=> &int(30) } int(10) int(30) ## \*\* instanceof 运算符支持字面量语法\*\* instanceof 的第一个运算数支持字面量,非对象型字面量检测的结果为 false var\_dump("literal" instanceof stdClass);//false var\_dump(42 instanceof stdClass);//false var\_dump(new stdClass() instanceof stdClass);//true ## **支持调用时参数的末尾跟随逗号,但是定义是不行的** function methodName($p1, $p2) { var\_dump($p1, $p2); } methodName(10, 20, );//10 20 ## **BC 数学函数** bcscale() 函数支持获取当前任意BC(精度的数学扩展)函数所使用的 scale。 bcscale(3);//设置所有bc数学函数的默认小数点保留位数 var\_dump(bcscale());//3 ## **废弃大小写不敏感的常量** 将 TRUE 作为第三个参数传递给 define() 会导致一个废弃警告 ## **命名捕获支持** mb\_ereg\_ \*系列函数现在支持命名捕获。类似于mb\_ereg()的匹配函数现在将使用其组号和名称返回命名捕获,类似于PCRE: ``` <pre class="calibre10">``` <span class="token4">mb_ereg</span><span class="token3">(</span><span class="token2">'(?<word>\w+)'</span><span class="token3">,</span> <span class="token2">'国'</span><span class="token3">,</span> $matches<span class="token3">)</span><span class="token3">;</span> <span class="token4">print_r</span><span class="token3">(</span>$matches<span class="token3">)</span><span class="token3">;</span><span class="token">//Array ( [0] => [0 => "国", 1 => "国", "word" => "国"];</span> <span class="token4">mb_ereg</span><span class="token3">(</span><span class="token2">'(?<word>\w+)'</span><span class="token3">,</span> <span class="token2">'国<=>家'</span><span class="token3">,</span> $matches<span class="token3">)</span><span class="token3">;</span> <span class="token4">print_r</span><span class="token3">(</span>$matches<span class="token3">)</span><span class="token3">;</span><span class="token">//Array ( [0] => [0 => "国", 1 => "国", "word" => "国"];</span> <span class="token4">mb_ereg</span><span class="token3">(</span><span class="token2">'(?<word>\w+)'</span><span class="token3">,</span> <span class="token2">'国家'</span><span class="token3">,</span> $matches<span class="token3">)</span><span class="token3">;</span> <span class="token4">print_r</span><span class="token3">(</span>$matches<span class="token3">)</span><span class="token3">;</span><span class="token">//Array ( [0] => 国家 [1] => 国家 [word] => 国家 )</span> ``` ``` 此外,mb\_ereg\_replace()现在支持 \\k<>和\\k''表示法来引用替换字符串中的命名捕获: ``` <pre class="calibre10">``` <span class="token">//mb_ereg_replace ($pattern , $replacement , $string中匹配) //在string中匹配pattern,匹配成功则替换成replacement</span> $str<span class="token1">=</span><span class="token4">mb_ereg_replace</span><span class="token3">(</span><span class="token2">'\s*(?<word>\w+)\s*'</span><span class="token3">,</span> <span class="token2">"_\k<word>_\k'word'_"</span><span class="token3">,</span> <span class="token2">' foo '</span><span class="token3">)</span><span class="token3">;</span> echo $str<span class="token3">;</span><span class="token">// => "_foo_foo_"</span> ``` ``` # **php7.4新特性** ## **预加载** `PHP`预加载可以极大的提高性能 - 优点:在`PHP 7.4`以前,如果你使用了框架来开发,每次请求文件就必须加载和重新编译。预加载在框架启动时在内存中加载文件,而且在后续请求中永久有效。 - 缺点:性能的提升会在其他方面花费很大的代价,每次预加载的文件发生改变时,框架需要重新启动。 ## **类属性现在支持类型声明** 除了`void`和`callable`外,所有的类型都支持 因此,我们可以放心使用`bool`,`int`,`float`,`string`,`array`,`object`,`iterable`,`self`,`parent` ``` <pre class="calibre10">``` class <span class="token4">User</span> <span class="token3">{</span> public int $id<span class="token3">;</span> public string $name<span class="token3">;</span> public <span class="token1">?</span>Foo $foo<span class="token3">;</span> <span class="token3">}</span> ``` ``` ## **短闭包函数** ``` <pre class="calibre10">``` array_map <span class="token3">(</span><span class="token5">function</span><span class="token3">(</span>$arr1_value<span class="token3">,</span> $arr2_value<span class="token3">,</span> $arrN_value<span class="token3">)</span><span class="token3">{</span> <span class="token">//return $arr1_value.$arr2_value.$arrN_value;</span> <span class="token3">}</span><span class="token3">,</span> $arr1<span class="token3">,</span> $arr2<span class="token3">,</span> $arrN <span class="token3">)</span><span class="token3">;</span> <span class="token">//原有特性</span> <span class="token5">function</span> <span class="token4">cube</span><span class="token3">(</span>$n<span class="token3">)</span><span class="token3">{</span> <span class="token5">return</span> <span class="token3">(</span>$n <span class="token1">*</span> $n <span class="token1">*</span> $n<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> $a <span class="token1">=</span> <span class="token3">[</span><span class="token6">1</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">,</span> <span class="token6">3</span><span class="token3">,</span> <span class="token6">4</span><span class="token3">,</span> <span class="token6">5</span><span class="token3">]</span><span class="token3">;</span> $b <span class="token1">=</span> <span class="token4">array_map</span><span class="token3">(</span><span class="token2">'cube'</span><span class="token3">,</span> $a<span class="token3">)</span><span class="token3">;</span> <span class="token4">print_r</span><span class="token3">(</span>$b<span class="token3">)</span><span class="token3">;</span> <span class="token">//新特性</span> $a <span class="token1">=</span> <span class="token3">[</span><span class="token6">1</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">,</span> <span class="token6">3</span><span class="token3">,</span> <span class="token6">4</span><span class="token3">,</span> <span class="token6">5</span><span class="token3">]</span><span class="token3">;</span> $res <span class="token1">=</span> <span class="token4">array_map</span><span class="token3">(</span><span class="token4">fn</span><span class="token3">(</span>$n<span class="token3">)</span> <span class="token1">=</span><span class="token1">></span> $n <span class="token1">*</span> $n <span class="token1">*</span> $n<span class="token3">,</span> $a<span class="token3">)</span><span class="token3">;</span> <span class="token4">print_r</span><span class="token3">(</span>$res<span class="token3">)</span><span class="token3">;</span> $a <span class="token1">=</span> <span class="token3">[</span><span class="token6">1</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">]</span><span class="token3">;</span> $b <span class="token1">=</span> <span class="token3">[</span><span class="token6">3</span><span class="token3">,</span> <span class="token6">4</span><span class="token3">,</span> <span class="token6">5</span><span class="token3">]</span><span class="token3">;</span> $res <span class="token1">=</span> <span class="token4">array_map</span><span class="token3">(</span><span class="token4">fn</span><span class="token3">(</span>$av<span class="token3">,</span>$bv<span class="token3">)</span> <span class="token1">=</span><span class="token1">></span> $av<span class="token1">*</span>$bv<span class="token3">,</span> $a<span class="token3">,</span>$b<span class="token3">)</span><span class="token3">;</span> <span class="token4">print_r</span><span class="token3">(</span>$res<span class="token3">)</span><span class="token3">;</span> $a <span class="token1">=</span> <span class="token3">[</span><span class="token6">1</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">]</span><span class="token3">;</span> $b <span class="token1">=</span> <span class="token3">[</span><span class="token6">3</span><span class="token3">,</span> <span class="token6">4</span><span class="token3">,</span> <span class="token6">5</span><span class="token3">]</span><span class="token3">;</span> $res <span class="token1">=</span> <span class="token4">array_map</span><span class="token3">(</span><span class="token4">fn</span><span class="token3">(</span><span class="token1">?</span>int $av<span class="token3">,</span><span class="token1">?</span>int $bv<span class="token3">)</span><span class="token3">:</span> int <span class="token1">=</span><span class="token1">></span> $av<span class="token1">*</span>$bv<span class="token3">,</span> $a<span class="token3">,</span>$b<span class="token3">)</span><span class="token3">;</span> <span class="token4">print_r</span><span class="token3">(</span>$res<span class="token3">)</span><span class="token3">;</span> <span class="token">//如果你想通过引用返回一个值,应该使用以下语法</span> fn<span class="token1">&</span><span class="token3">(</span>$x<span class="token3">)</span> <span class="token1">=</span><span class="token1">></span> $x <span class="token">//总结:</span> <span class="token">//它们以fn关键字开始</span> <span class="token">//它们只能有一个表达式,即return语句</span> <span class="token">//不允许return关键字</span> <span class="token">//参数和返回类型可以是限定类型</span> ``` ``` ## **Null 合并运算符** ``` <pre class="calibre10">``` $data<span class="token3">[</span><span class="token2">'date'</span><span class="token3">]</span> <span class="token1">?</span><span class="token1">?</span><span class="token1">=</span> <span class="token5">new</span> <span class="token4">DateTime</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//相当于之前的</span> $data<span class="token3">[</span><span class="token2">'date'</span><span class="token3">]</span> <span class="token1">=</span> $data<span class="token3">[</span><span class="token2">'date'</span><span class="token3">]</span> <span class="token1">?</span><span class="token1">?</span> <span class="token5">new</span> <span class="token4">DateTime</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> 或: <span class="token5">if</span> <span class="token3">(</span><span class="token1">!</span><span class="token4">isset</span><span class="token3">(</span>$data<span class="token3">[</span><span class="token2">'date'</span><span class="token3">]</span><span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> $data<span class="token3">[</span><span class="token2">'date'</span><span class="token3">]</span> <span class="token1">=</span> <span class="token5">new</span> <span class="token4">DateTime</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> ``` ``` ## **数组扩展运算符** 现在你可以在数组中使用展开运算符: **注意**:只对数字索引有效 ``` <pre class="calibre10">``` $arrayA <span class="token1">=</span> <span class="token3">[</span><span class="token6">1</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">,</span> <span class="token6">3</span><span class="token3">]</span><span class="token3">;</span> $arrayB <span class="token1">=</span> <span class="token3">[</span><span class="token6">4</span><span class="token3">,</span> <span class="token6">5</span><span class="token3">]</span><span class="token3">;</span> $result <span class="token1">=</span> <span class="token3">[</span><span class="token6">0</span><span class="token3">,</span> <span class="token3">.</span><span class="token3">.</span><span class="token3">.</span>$arrayA<span class="token3">,</span> <span class="token3">.</span><span class="token3">.</span><span class="token3">.</span>$arrayB<span class="token3">,</span> <span class="token6">6</span> <span class="token3">,</span><span class="token6">7</span><span class="token3">]</span><span class="token3">;</span> <span class="token">// [0, 1, 2, 3, 4, 5, 6, 7]</span> ``` ``` ## **自定义对象序列化** 添加了两个新的魔术方法:`__serialize` 和`__unserialize` ## **数字分隔符** 允许使用下划线更直观的分隔数值 ``` <pre class="calibre10">``` $unformattedNumber <span class="token1">=</span> <span class="token6">107925284.88</span><span class="token3">;</span> <span class="token">//新特性</span> $formattedNumber <span class="token1">=</span> <span class="token6">107</span>_925_284<span class="token3">.</span><span class="token6">88</span><span class="token3">;</span> ``` ``` ## **支持反射引用** `PHP 7.4`将会新增`ReflectionReference`类 ## **改进的类型差异(协变返回和逆变参数)** [协变和逆变](https://link.zhihu.com/?target=https%3A//zh.wikipedia.org/wiki/%25E5%258D%258F%25E5%258F%2598%25E4%25B8%258E%25E9%2580%2586%25E5%258F%2598) [百度百科的解释](https://link.zhihu.com/?target=https%3A//baike.baidu.com/item/%25E5%258D%258F%25E5%258F%2598) 协变与逆变(Covariance and contravariance )是在计算机科学中,描述具有父/子型别关系的多个型别通过型别构造器、构造出的多个复杂型别之间是否有父/子型别关系的用语。 - Invariant (不变): 包好了所有需求类型 - Covariant (协变):类型从通用到具体 - Contravariant (逆变): 类型从具体到通用目前,PHP 主要具有`Invariant`的参数类型,并且大多数是`Invariant`的返回类型,这就意味着当我是 T 参数类型或者返回类型时,子类也必须是 T 的参数类型或者返回类型。但是往往会需要处理一些特殊情况,比如具体的返回类型,或者通用的输入类型。而[RFC](https://link.zhihu.com/?target=https%3A//wiki.php.net/rfc/covariant-returns-and-contravariant-parameters)的这个提案就提议,PHP7.4 添加协变返回和逆变参数,以下是提案给出来的例子:协变返回: ``` <pre class="calibre17">``` class <span class="token4">Parent</span> <span class="token3">{</span><span class="token3">}</span> class <span class="token4">Child</span> extends <span class="token4">Parent</span> <span class="token3">{</span><span class="token3">}</span> class <span class="token4">A</span> <span class="token3">{</span> public <span class="token5">function</span> <span class="token4">covariantReturnTypes</span><span class="token3">(</span><span class="token3">)</span><span class="token3">:</span> Parent <span class="token3">{</span> <span class="token">/* … */</span> <span class="token3">}</span> <span class="token3">}</span> class <span class="token4">B</span> extends <span class="token4">A</span> <span class="token3">{</span> public <span class="token5">function</span> <span class="token4">covariantReturnTypes</span><span class="token3">(</span><span class="token3">)</span><span class="token3">:</span> Child <span class="token3">{</span> <span class="token">/* … */</span> <span class="token3">}</span> <span class="token3">}</span> ``` ```