PHP7.0特性
函数变更
参考:
关于list处理方式的变更
list不再以反向的顺序来进行赋值
list
现在会按照变量定义的顺序来给他们进行赋值,而非反过来的顺序。 通常来说,这只会影响list
与数组的[]
操作符一起使用的案例,如下所示:
1 |
|
1 |
|
推荐不要依赖list
的赋值顺序,因为这是一个在未来也许会变更的实现细节。
list 结构现在不再能是空的
list结构现在不再能是空的。如下的例子不再被允许:
1 |
|
list不再能解开string
list
不再能解开字符串(string)变量。 你可以使用str_split
来代替它
foreach的变化
foreach
发生了细微的变化,控制结构, 主要围绕阵列的内部数组指针和迭代处理的修改。
foreach不再改变内部数组指针
在PHP7之前,当数组通过foreach
迭代时,数组指针会移动。现在开始,不再如此,见下面代码
1 |
|
结果
1 |
|
foreach通过值遍历时,操作的值为数组的副本
当默认使用通过值遍历数组时,foreach
实际操作的是数组的迭代副本,而非数组本身。这就意味着,foreach
中的操作不会修改原数组的值。
foreach通过引用遍历时,有更好的迭代特性
当使用引用遍历数组时,现在 foreach
在迭代中能更好的跟踪变化。例如,在迭代中添加一个迭代值到数组中,参考下面的代码:
1 |
|
结果
1 |
|
filter_var转换十六进制数字
filter_var
函数可以用于检查一个 string
是否含有十六进制数字,并将其转换为integer
:
1 |
|
通过 define 定义常量数组
Array 类型的常量现在可以通过 define()
来定义。在 PHP5.6 中仅能通过 const
定义。
1 |
|
为unserialize()提供过滤
这个特性旨在提供更安全的方式解包不可靠的数据。它通过白名单的方式来防止潜在的代码注入。
可选白名单参数也可以是布尔数据,如果是FALSE就会将所有的对象都转换为__PHP_Incomplete_Class
对象。TRUE是无限制。也可以传入类名实现白名单。
1 |
|
session_start可以加入一个数组
session_start()
可以接受一个 array
作为参数, 用来覆盖 php.ini 文件中设置的 会话配置选项。
在调用 session_start()
的时候, 传入的选项参数中也支持 session.lazy_write
行为, 默认情况下这个配置项是打开的。它的作用是控制 PHP 只有在会话中的数据发生变化的时候才 写入会话存储文件,如果会话中的数据没有发生改变,那么 PHP 会在读取完会话数据之后, 立即关闭会话存储文件,不做任何修改,可以通过设置 read_and_close
来实现。
例如,下列代码设置 session.cache_limiter
为 private,并且在读取完毕会话数据之后马上关闭会话存储文件。
1 |
|
preg_replaces不再支持/e修饰符
1 |
|
但是有新的函数preg_replace_callback
dirname增加了参数
dirname()
增加了可选的第二个参数, depth
, 获取当前目录向上 depth
级父目录的名称
1 |
|
system等函数对NULL增加了保护.
exec()
, system()
and passthru()
函数对 NULL 增加了保护(我也不知道啥意思。
增加整数除法函数 intdiv
新加的函数 intdiv()
用来进行 整数的除法运算。
1 |
|
增加preg_replace_callback_array
在 PHP 7 之前,当使用 preg_replace_callback()
函数的时候, 由于针对每个正则表达式都要执行回调函数,可能导致过多的分支代码。 而使用新加的 preg_replace_callback_array()
函数, 可以使得代码更加简洁。
现在,可以使用一个关联数组来对每个正则表达式注册回调函数, 正则表达式本身作为关联数组的键, 而对应的回调函数就是关联数组的值。
1 |
|
增加Closure::call()
Closure::call() 现在有着更好的性能,简短干练的暂时绑定一个方法到对象上闭包并调用它。
1 |
|
被移除的函数
call_user_method
和call_user_method_array
所有的
ereg*
函数mcrypt
的一部分废弃函数所有
ext/mysql
函数所有
ext/mssql
函数dl in PHP-FPM
dl()在 PHP-FPM 不再可用,在 CLI 和 embed SAPIs 中仍可用。
语法变更
关于变量处理的变化
PHP 7 现在使用了抽象语法树来解析源代码。这使得许多由于之前的PHP的解释器的限制所不可能实现的改进得以实现。 但出于一致性的原因导致了一些特殊例子的变动,而这些变动打破了向后兼容。 在这一章中将详细介绍这些例子。
关于间接使用变量、属性和方法的变化
对变量、属性和方法的间接调用现在将严格遵循从左到右的顺序来解析,而不是之前的混杂着几个特殊案例的情况。 下面这张表说明了这个解析顺序的变化。
间接调用的表达式的新旧解析顺序
表达式 | PHP 5 的解析方式 | PHP 7 的解析方式 |
---|---|---|
$$foo['bar']['baz'] |
${$foo['bar']['baz']} |
($$foo)['bar']['baz'] |
$foo->$bar['baz'] |
$foo->{$bar['baz']} |
($foo->$bar)['baz'] |
$foo->$bar['baz']() |
$foo->{$bar['baz']}() |
($foo->$bar)['baz']() |
Foo::$bar['baz']() |
Foo::{$bar['baz']}() |
(Foo::$bar)['baz']() |
使用了旧的从右到左的解析顺序的代码必须被重写,明确的使用大括号来表明顺序(参见上表中间一列)。 这样使得代码既保持了与PHP 7.x的前向兼容性,又保持了与PHP 5.x的后向兼容性。
这同样影响了global 关键字。如果需要的话可以使用大括号来模拟之前的行为。
1 |
|
8进制字符容错率降低
在php5版本,如果一个八进制字符如果含有无效数字,该无效数字将被静默删节。但是在php7.0.0里面会触发一个解析错误。同样在php7.0.0以后被改回去。
1 |
|
负位移运算
以负数形式进行的位移运算将会抛出一个 ArithmeticError:
1 |
|
结果
1 |
|
超范围后产生位移
超出 integer
位宽的位移操作(无论哪个方向)将始终得到 0 作为结果。在从前,这一操作是结构依赖的
十六进制字符串规范
十六进制字符串不再被认为是数字
目前截至最新的PHP7.3版本依然没有改回去的征兆,官方称不会在改了。
1 |
|
结果:
左边php5.6,右边php7.2
filter_var() 函数可以用于检查一个 string 是否含有十六进制数字,并将其转换为integer:
1 |
|
由于新的 Unicode codepoint escape syntax语法, 紧连着无效序列并包含\u{ 的字串可能引起致命错误。 为了避免这一报错,应该避免反斜杠开头。
移除了 ASP 和 script PHP 标签
使用类似 ASP 的标签,以及 script 标签来区分 PHP 代码的方式被移除。 受到影响的标签有:
开标签 | 闭标签 |
---|---|
<% |
%> |
<%= |
%> |
<script language="php"> |
</script> |
yield 变更为右联接运算符
在使用 yield
关键字的时候,不再需要括号, 并且它变更为右联接操作符,其运算符优先级介于 print 和 => 之间。 这可能导致现有代码的行为发生改变:
1 |
|
可以通过使用括号来消除歧义。
关于对引用数组元素创建的变量的顺序变化
有如下代码
1 |
|
结果
1 |
|
NULL合并运算符
由于日常使用中存在大量同时使用三元表达式和 isset()
的情况, 我们添加了null合并运算符 (??) 这个语法糖。如果变量存在且值不为NULL, 它就会返回自身的值,否则返回它的第二个操作数。
1 |
|
太空船操作符(组合比较符)
太空船操作符用于比较两个表达式。当$a小于、等于或大于$b时它分别返回-1、0或1。 比较的原则是沿用 PHP 的常规比较规则进行的。
1 |
|
匿名类
现在支持通过new class 来实例化一个匿名类,这可以用来替代一些“用后即焚”的完整类定义。
1 |
|
Unicode codepoint 转译语法
这接受一个以16进制形式的 Unicode codepoint,并打印出一个双引号或heredoc包围的 UTF-8 编码格式的字符串。 可以接受任何有效的 codepoint,并且开头的 0 是可以省略的。
1 |
|
导入use声名组
从同一 namespace
导入的类、函数和常量现在可以通过单个 use 语句 一次性导入了。
1 |
|
放宽了保留词限制
现在允许全局保留词用于类/接口/Trait 中的属性、常量和方法名。 在引入新关键词时,此变更减少了对向后兼容的破坏,避免了 API 命名的限制。
使用流畅的接口实现内部 DSL 时,这非常有用:
1 |
|
唯一的限制是: class关键词不能用于常量名,否则会和 类名解析语法冲突 (ClassName::class)。
(弃用)PHP4 风格的构造函数
PHP4 风格的构造函数(方法名和类名一样)将被弃用,并在将来移除。 如果在类中仅使用了 PHP4 风格的构造函数,PHP7 会产生 E_DEPRECATED 警告。 如果还定义了 __construct() 方法则不受影响。
1 |
|
(弃用)静态调用非静态的方法
废弃了静态调用未声明成 static 的方法,未来可能会彻底移除该功能。
1 |
|