php7

PHP 7.4 新特新速看,预加载了解一下~

PHP 7.4 ,下一个 PHP 7 较小的发布版,期望在 2019 年 11 月 28 日发布。因此,现在是时候让大家深入了解这个版本添加哪些新特性使 PHP 更快、更可靠。

虽然 PHP 7.4 显著地提升了性能和提高代码可读性,PHP 8 才将会是 PHP 性能真正的里程碑,这在 JIT inclusion 的提案显示已充分证明。

现在去无偿迁移

总之,今天我们将概览 PHP 7.4 最瞩目的特性和性能提升。在继续探索之前,你最好记住以下重要的时间节点:

6 月 6 日:PHP 7.4 Alpha 17 月 18 日:PHP 7.4 Beta 1 – Feature freeze(特性固化)11 月 28 日:PHP 7.4 GA Release你可从 the official RFC page 查看全部新特性和功能。

PHP 7.4 发布日期:

PHP 7.4 将于 2019 年 11 月 28 日发布。这是 PHP 7 的下一个小版本,会再次提升性能,提高代码的可读性和可维护性。

PHP 7.4 有什么新功能?

在这边文章中,我们将讨论 PHP 7.4 最终版本中应该增加一些变化和特性:

抛弃 array_merge :PHP 7.4 在数组表达式中引入了扩展运算符

从 PHP 5.6 开始,参数解析 是一种解析数组并遍历到参数列表中的语法。要解析一个或遍历一个数组,必须以 ...(三个点)作为前缀,如下所示:

functiontest(...$args){var_dump($args);}test(1,2,3);现在 PHP 7.4 的 RFC 建议将这个功能扩展到数组定义中:

$arr=[...$args];扩展操作符在数组表达式 第一个明显的优点是性能。RFC 文档:

扩展操作符应该比 array_merge 性能更好。不仅是因为扩展操作符是一种语言结构,array_merge 是一个函数,还因为可以优化编译常量数组的性能。

扩展操作符一个重要的优点是支持任何可遍历的对象, array_merge 函数只支持数组。

下面是数组表达式中的参数解析示例:

$parts=['apple','pear'];$fruits=['banana','orange',...$parts,'watermelon'];var_dump($fruits);如果你在 PHP 7.3 或更早版本中运行此代码,PHP 将抛出解析错误:

Parse error: syntax error, unexpected '...'(T_ELLIPSIS), expecting ']' in /app/spread-operator.php on line 3相反,PHP 7.4 将返回一个数组:

array(5){[0]=>string(6)"banana"[1]=>string(6)"orange"[2]=>string(5)"apple"[3]=>string(4)"pear"[4]=>string(10)"watermelon"}RFC 声明我们可以多次扩展同一个数组。而且,我们可以在数组中的任何地方使用扩展运算符语法,因为可以在扩展运算符之前或之后添加普通元素。所以,就像下面代码所示的那样:

$arr1=[1,2,3];$arr2=[4,5,6];$arr3=[...$arr1,...$arr2];$arr4=[...$arr1,...$arr3,7,8,9];也可以将函数返回的数组直接合并到另一个数组:

functionbuildArray(){return['red','green','blue'];}$arr1=[...buildArray(),'pink','violet','yellow'];PHP 7.4 输出以下数组:

array(6){[0]=>string(3)"red"[1]=>string(5)"green"[2]=>string(4)"blue"[3]=>string(4)"pink"[4]=>string(6)"violet"[5]=>string(6)"yellow"}我们也可以使用 生成器:

functiongenerator(){for($i=3;$i<=5;$i++){yield$i;}}$arr1=[0,1,2,...generator()];但是我们不允许合并通过引用传递的数组。考虑以下的例子:

$arr1=['red','green','blue'];$arr2=[...&$arr1];如果我们尝试按引用合并数组,则 PHP 会引发以下解析错误:

Parse error: syntax error, unexpected '&' in /app/spread-operator.php on line 3无论如何,如果第一个数组的元素是通过引用存储的,则它们也将通过引用存储在第二个数组中。这是一个例子:

$arr0='red';$arr1=[&$arr0,'green','blue'];$arr2=['white',...$arr1,'black'];这就是我们使用 PHP 7.4 所获得的:

array(5){[0]=>string(5)"white"[1]=>&string(3)"red"[2]=>string(5)"green"[3]=>string(4)"blue"[4]=>string(5)"black"}The Spread operator 提案以 43 票对 1 票获得通过。

箭头函数 2.0 (短闭包)

对于 PHP 而言,匿名函数 被认为十分冗长并且难以使用和维护的。RFC 提出了更短并且语法更简洁的 * 箭头函数(短闭包),能够在很大程度上使我们的 PHP 代码更简洁。

考虑如下例子:

functioncube($n){return($n*$n*$n);}$a=[1,2,3,4,5];$b=array_map('cube',$a);print_r($b);PHP 7.4 允许使用更简洁的语法,上面的函数可以重写为如下:

$a=[1,2,3,4,5];$b=array_map(fn($n)=>$n*$n*$n,$a);print_r($b);目前,要感谢 use 语法,匿名函数 (闭包) 可以从父作用域里继承已经定义的变量:

$factor=10;$calc=function($num)use($factor){return$num*$factor;};但是在 PHP 7.4 中, 在父作用域里定义的变量被隐式捕获(隐式作用域绑定)了。如此一来,我们可用只用一行代码重写整个上面的函数:

$factor=10;$calc=fn($num)=>$num*$factor;我们可以像使用 use(变量) 一样,直接使用在父作用域里定义的变量,并且它也不会修改父作用域的变量。

新的语法对我们构建更可读可维护的代码带来了极大的改善。我们也可以使用参数和返回类型、默认值、变长参数列表(可变函数),可以传递或返回引用等等。然后呢,短闭包还可以被用作类方法,可以像常规一样使用 $this。

RFC 已经以 51 票对 8 票通过了,所以我们可以期待在 PHP 7.4 新增功能里见到它。

空合并赋值操作符

在 PHP 7 中,当我们需要同时使用三元运算符和 isset() 时,合并运算符(??)就可以派上用场了。如果第一个操作数是存在并且不为 NULL,则返回该操作数。否则返回第二个操作数。示例如下:

$username=$_GET['user']??'nobody';这段代码很简单:获取请求参数,如果不存在,则设置一个默认值。它的意思很明确,但如果出现像下方这个来自 RFC 中示例这种更长的变量名呢?

$this->request->data['comments']['user_id']=$this->request->data['comments']['user_id']??'value';从长远的角度看,这段代码可能有点难以维护。因此,为了帮助开发人员编写更直观的代码,这个 RFC 建议引入空合并赋值操作符(??=)。因此,我们可以编写如下代码进行替代:

$this->request->data['comments']['user_id']??='value';如果左侧的参数是 null,则使用右侧参数的值。请注意,当合并运算符是比较运算符时,??= 就是一个赋值运算符。

这项建议以 37:4 的票获得通过。

类型属性 2.0

参数类型声明(或类型提示)允许对将要传递给函数或者类方法的变量类型进行限定。该功能自 PHP 5 起可用,PHP 7.2 起可以使用对象作为数据类型。现在 PHP 7.4 通过添加 类属性类型声明 进一步扩展了类型提示。以下是一个基本的示例:

classUser{public int $id;public string $name;}支持 void 与 callable 以外的所有类型

public int $scalarType;protected ClassName $classType;private?ClassName $nullableClassType;这项 RFC 解释了为什么不支持 void 和 callable 返回值的原因:

不支持 void 类型,因为它没有用到并且语义不明确。不支持 callable 类型,因为其行为取决于上下文。

这样我们就可以安全地使用 bool, int, float, string, array, object, iterable, self, parent, 任何类或接口名称,并且可以为空 types (?type)。

类型可以用于静态属性:

publicstatic iterable $staticProp;也可以使用 var 标记:

var bool $flag;可以设置默认属性值,当然必须与声明的属性类型匹配,但是只有可为空的属性可以具有默认的 null 值:

public string $str="foo";public?string $nullableStr=null;相同类型适用于单个声明中的所有属性:

public float $x,$y;如果我们对属性类型进行错误处理会怎样?考虑以下代码:

classUser{public int $id;public string $name;}$user=newUser;$user->id=10;$user->name=[];在上面的代码中,我们声明了字符串属性类型,但是我们将数组设置为属性值。在这种情况下,我们将收到以下致命错误:

Fatal error: Uncaught TypeError: Typed property User::$name must be string,array used in /app/types.php:9该 RFC 已以 70 票对 1 票获得批准。

弱引用

在这项 RFC 中,PHP 7.4 引入了 WeakReference (弱引用) 类型,这样开发者就可以保留对对象的引用,而这不会阻止对象本身被破坏。

目前,PHP 通过使用诸如 pecl-weakref 之类的扩展名来支持弱引用。无论如何,新的 API 与记录的 WeakRef 类不同。

这是 一份简单的 demo 来自这项提议的作者 Nikita Popov。

$object=newstdClass;$weakRef=WeakReference::create($object);var_dump($weakRef->get());unset($object);var_dump($weakRef->get());第一个 var_dump 打印对象 object(stdClass)#1 (0) {} ,第二个 var_dump 打印引用为 NULL,因为所引用的对象已被销毁。

该 RFC 以 28 票对 5 票获得通过。

协变量返回和协变量参数

方差 是类层次结构的一个属性,描述了类型构造函数的类型如何影响 subtypes。通常,类型构造函数可以是:

Invariant:如果超类型的类型约束子类型的类型。Covariant:如果保留类型的顺序(类型从更具体到更一般)。Contravariant:如果它颠倒了顺序(类型从更通用到更具体地排序)。目前,PHP 的参数和返回类型大部分不变,只有少数例外。该 RFC 建议允许在参数类型和返回类型上进行协方差和协变,并提供一些代码示例。

这是 协变量返回 的一个简单例子:

interfaceFactory{functionmake(): object;}classUserFactoryimplementsFactory{functionmake(): User;}这个是 协变量参数 一个示例:

interfaceConcatable{functionconcat(Iterator $input);}classCollectionimplementsConcatable{// accepts all iterables, not just Iteratorfunctionconcat(iterable $input){/* . . . */}}请参阅 RFC 以更详细地了解 PHP 7.4 协变量返回和协变量参数。

该 RFC 以 39 对 1 票获得通过。

预加载

这项提议 来自 Dmitry Stogov ,这是我们的受支持的提议之一,因为它可以显着提高 PHP 的性能。预加载 是在模块初始化时将库和框架加载到 OPCache 的过程,详细了解 [PHP 生命周期]。

PHP 生命周期 (资源镜像: PHP Internals)

用 Dmitry 的话来说,预加载是这样工作的:

在服务器启动时(在运行任何应用程序代码之前),我们可以将一组 PHP 文件加载到内存中,并使它们的内容 永久可用 给该服务器将服务的所有后续请求。与内部实体完全一样,这些文件中定义的所有函数和类也可用于开箱即用的请求。

这些文件在服务器启动时加载,在任何应用程序之前执行,并且对以后的任何请求均可用。就性能而言,这很棒。

Preloading is controlled by a specific php.ini directive: opcache.preload. This directive specifies a PHP script to be compiled and executed at server start-up. This file can be used to preload additional files, either including them or via the opcache_compile_file() function (read more on PHP documentation).预加载由特定的 php.ini 指令控制:opcache.preload。该指令指定在服务器启动时要编译和执行的 PHP 脚本。此文件可用于预加载其他文件,包括它们或通过 opcache_compile_file() 函数(有关更多信息,请参见 [PHP 文档](https://www.php.net/manual/en/function.opc... -file.php))。

但是有一个缺点。实际上,RFC 里有明确声明:

预加载的文件将永远保留在 opcache 内存中。不重新启动另一台服务器,对其相应源文件的修改将不会生效。

但是,在预加载的文件中定义的所有函数将被永久加载到 PHP 函数和类表中,并且对于以后的每个请求均可用。即使这些改进可能有很大的不同,也会带来良好的性能改进。

您可以在官方的 预加载 RFC 页面 上阅读有关预加载的限制和例外的更多信息。

新的自定义对象序列化机制

这是 Nikita Popov 的另一项提议

当前,我们有两种不同的机制可以在 PHP 中对对象进行自定义序列化:

__sleep() 和 __wakeup() 魔术方法Serializable 接口根据 Nikita 的说法,这两个选项都存在导致复杂且不可靠的代码的问题。您可以在 RFC 中深入研究此主题。在这里我只是提到新的序列化机制应该通过提供两种新的魔术方法__serialize() 和 __unserialize() 来解决这些问题,这两种方法结合了两个现有机制。

该提案以 20 票对 7 票获得通过。

已废弃

PHP 7.4 不推荐使用以下功能。要获得更全面的弃用列表,请查看 PHP 7.4 升级说明。

更改串联运算符的优先级

当前,在 PHP 中,+ 和 - 算术运算符以及 . 字符串运算符保持关联性并具有相同的优先级。(阅读更多相关信息运算符优先级)

例如,考虑以下行:

echo"sum: ".$a+$b;在 PHP 7.3 中,此代码产生以下警告:

Warning:A non-numeric value encountered in /app/types.php on line 4这是因为从左到右评估了串联。与编写以下代码相同:

echo("sum: ".$a)+$b;这项 RFC 建议更改运算符的优先级,给 . 赋予比 + 和 - 运算符低的优先级,以便总是在字符串连接之前执行加法和减法。该行代码应等效于以下内容:

echo"sum: ".($a+$b);这是一个两步建议:

从 7.4 版开始,PHP 在遇到带有 + ,- 和 . 的非括号表达式时应发出弃用通知。这些运算符的优先级的实际更改应在 PHP 8 中添加。两项提议均以绝大多数票获得批准。

弃用左联想三元运算符

在 PHP 中,与许多其他语言不同,三元运算符是左关联的。根据 Nikita Popof 的说法,这对于在不同语言之间进行切换的开发者可能会造成混淆。

当前,在 PHP 中,以下代码是正确的:

$b=$a==1?'one':$a==2?'two':$a==3?'three':'other';解释为:

$b=(($a==1?'one':$a==2)?'two':$a==3)?'three':'other';这可能会导致错误,因为这可能不是我们打算要做的。因此,该 RFC 建议弃用并删除三元运算符的左关联性,并强制开发人员使用括号。

这是另外两个步骤的建议:

从 PHP 7.4 开始,不显式使用括号的嵌套三元将抛出弃用警告。从 PHP 8.0 开始,将出现编译时错误。该提案以 35 到 10 票获得批准。

在 Docker 中安装和运行 PHP 7.4

想在 Docker 上试试吗?幸运的是在 Docker 环境下你不需要再手动编译和配置 PHP 7.4 了 。如果你已经安装了 Docker , 那只需要花几秒钟安装这个非官方的 PHP-FPM 7.4 Docker 镜像 就可以在命令行中进行测试了。

如果你想要运行 PHP 7.4 的代码到你的浏览器中,那你还需要给 Docker 安装 Nginx 或 Apache 镜像。不用担心,只要按照 开发指南。将示例命令拷贝粘贴到命令行中并运行,就可以了。

摘要

在这篇文章中我们简单介绍了 PHP 7.4 发行版大量的更新和新增功能。如果你还想要了解完整的功能列表和正式的 RFC 官方文档,可以参考这些资源:

PHP 7.4 要求说明PHP 7.4 升级说明PHP 7.4 准备任务

展开
收起

PHP7.0 的新特性

PHP7.0 的新特性经常会被面试官问到,在平时的项目开发中运用它们也会提升一定的代码质量和代码运行性能,可见这个知识点的重要性。不过有很多人都没有去系统的了解掌握,今天我刚好系统整理了一番分享出来。

图片版

文字版

1.新增了标量类型声明和函数的返回值类型声明例如:<?php declare(strict_types=1)//1:严格模式 0:强制模式(默认)classOrderServiceextendsBaseService{.../** * 所有订单详情都是通过这个入口 * @param $orderNo * @return array|mixed * @throws Exception */publicfunction getOrderDetailByOrderNo(string $orderNo): array{ $order = $this->model->getByFields(['order_no'=> $orderNo]);if(empty($order)){return[];}return(newOrderFactory)->getOrder($order['order_type'])->getOrderDetailByOrderNo($orderNo);}}2.太空船运算符(组合比较符):<=>例如:$c = $a <=> $b若 $a>$b,则 $c=1若 $a=$b,则 $c=0若 $a<$b,则 $c=-13. NULL合并运算:??PHP7 之前:$c = isset($b)?$b:0;PHP7+:$c = $b??0;4.定义常量数组:define("ARR",[1,2,3])5.新增抽象语法树AST(高度解耦)PHP7 之前:PHP 代码->Parser语法解析-> OPCODE ->执行PHP7+:PHP 代码->Parser语法解析-> AST -> OPCODE ->执行6.命名空间引用优化PHP7 之前:useFooLibrary\Bar\Baz\ClassA;useFooLibrary\Bar\Baz\ClassB;PHP7+:useFooLibrary\Bar\Baz\{ ClassA,ClassB};7.反序列化函数Unserialize()提供更安全的过滤特性8.新增整除函数intdiv()例如:intdiv(10,3)结果:39.错误处理更友好*在PHP7+中,很多致命错误以及可恢复的致命错误,都被转换为异常来处理了。这些异常继承自Error类,此类实现了Throwable接口(所有异常都实现了这个基础接口)* PHP7+进一步方便开发者处理,让开发者对程序的掌控能力更强.因为在默认情况下,Error会直接导致程序中断,而PHP7+则提供捕获并且处理的能力,让程序继续执行下去,为程序员提供更灵活的选择10.新增匿名类通过newclass来实例化一个匿名类,可以用来替代一些"用后即焚"的完整类定义例如:<?phpinterfaceLogger{publicfunction log(string $msg);}classApplication{private $logger;publicfunction getLogger():Logger{return $this->logger;}publicfunction setLogger(Logger $logger){ $this->logger = $logger;}}$app =newApplication;// 使用 new class 创建匿名类$app->setLogger(newclassimplementsLogger{publicfunction log(string $msg){print($msg);}});$app->getLogger()->log("我的第一条日志");结果:我的第一条日志11.新增两个更安全的伪随机生成器函数random_bytes()和random_int()12.Closure::call()有着更好的性能,将一个闭包函数动态绑定到一个新的对象实例并调用执行该函数例如:<?phpclass A {private $x =1;}// PHP 7 之前版本定义闭包函数代码$getXCB =function(){return $this->x;};// 闭包函数绑定到类 A 上$getX = $getXCB->bindTo(new A,'A');echo $getX();// PHP 7+ 代码$getX =function(){return $this->x;};echo $getX->call(new A);13.移除扩展:ereg、mssql、mysql

展开
收起

PHP 7.2:一切只为更好的安全性和代码处理

【IT168资讯】PHP 7.2是流行服务器端Web开发语言的最新版本,具有许多功能和修复。

2017年11月30日,发布了PHP 7系列的第二个功能更新。此前,PHP 7.0曾在2015年12月首次亮相,升级提供了之前PHP迭代性能的两倍。

PHP 7.2中的新安全特性

PHP 7.2版本提供了多项安全改进:

1. 用于安全散列密码的Argon2算法解决了当前算法的不足之处,它是针对最高内存填充率而设计的。

2. 现在,用于认证加密的Libsodium密码库是一个核心扩展,还提供高速椭圆密码术。

3. SSL / TLS(安全套接字层/传输层安全性)常量得到了改进。

4. Mcrypt密码库扩展已被删除。PHP的开发人员已经表示,Mcrypt抑制了PHP语言的发展,并充当了“弃用软件”的角色。

PHP 7.2改进了编程功能

PHP 7.2有几个新增的编程功能:

1. 在对象/数组转换中,数字键转换解决了Zend引擎的问题。引擎的数组哈希表可以包含数字字符串,而对象哈希表可以有整数键。在这种情况下,PHP代码找不到密钥。在PHP 7.2中的修复中,数组或对象散列表的键将根据需要进行转换,因此对象中的数字字符串属性名称变成整型数组键,反之亦然,从而解决无法访问的属性问题。

2. 对象类型注解修复了开发人员无法声明需要通过对象作为参数传递的函数,或声明函数应返回对象的情况。该修复程序使用对象作为参数类型和作为返回类型。

3. HashContext作为对象迁移散列扩展,以使用对象扩展而不使用资源。

4. 使用标量参数、null参数或不实现Countable接口的对象调用count()函数时,会添加新的警告。

PHP 7.2可以从php.net website下载。

展开
收起

配置nginx支持php7.0

[root@redhat7 ~]# wget http://am1.php.net/get/php-7.1.2.tar.gz/from/this/mirror

[root@redhat7 ~]# tar xzvf php-7.1.2.tar.gz

[root@redhat7 ~]# cd php-7.1.2/

[root@redhat7 ~]# ./configure --prefix=/usr/local/php --enable-fpm

[root@redhat7 php-7.1.2]# make&&make install

查看是否成功编译安装PHP

[root@redhat7 php-7.1.2]# php -v

PHP 7.1.2 (fpm-fcgi) (built: Apr 14 2017 20:21:53)

Copyright (c) 1997-2017 The PHP Group

Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

编译安装完成后PHP不具备配置文件php.ini,此时只需复制php.ini-production到 /usr/local/lib/php.ini即可,php.ini文件一般在/usr/local/lib/和/etc目录下

[root@localhost php-7.1.2]# cp php.ini-production /usr/local/lib/php.ini

[root@redhat7 php]# /usr/local/php/sbin/php-fpm

[14-Apr-2017 20:59:49] ERROR: failed to open configuration file '/usr/local/php/etc/php-fpm.conf': No such file or directory (2)

[14-Apr-2017 20:59:49] ERROR: failed to load configuration file '/usr/local/php/etc/php-fpm.conf'

[14-Apr-2017 20:59:49] ERROR: FPM initialization failed

启动php-fpm发现缺乏配置文件/usr/local/php/etc/php-fpm.conf

此时只需复制php-fpm的配置文件在安装php时提供的配置文件的模版/usr/local/php/etc/php-fpm.conf.default到相应/usr/local/php/etc/php-fpm.conf即可

[root@redhat7 etc]# /usr/local/php/sbin/php-fpm

[14-Apr-2017 21:14:32] WARNING: Nothing matches the include pattern '/usr/local/php/etc/php-fpm.d/*.conf' from /usr/local/php/etc/php-fpm.conf at line 125.

[14-Apr-2017 21:14:32] ERROR: No pool defined. at least one pool section must be specified in config file

[14-Apr-2017 21:14:32] ERROR: failed to post process the configuration

[14-Apr-2017 21:14:32] ERROR: FPM initialization failed

[root@redhat7 etc]# cp php-fpm.conf.default /usr/local/php/etc/php-fpm.conf

[root@redhat7 etc]# cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf

[root@redhat7 etc]# /etc/init.d/php-fpm

[14-Apr-2017 21:23:02] ERROR: unable to bind listening socket for address '127.0.0.1:9000': Address already in use (98)

[14-Apr-2017 21:23:02] ERROR: FPM initialization failed

[root@redhat7 etc]# netstat -nldp|grep 9000

tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 3721/php-fpm: maste

[root@redhat7 php-7.1.2]# cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm

[root@redhat7 php-7.1.2]# chmod a+x /etc/init.d/php-fpm

[root@redhat7 php-7.1.2]# ll /etc/init.d/php-fpm

-rwxr-xr-x 1 root root 2401 4月 14 21:26 /etc/init.d/php-fpm

[root@redhat7 php-7.1.2]# /etc/init.d/php-fpm start

Starting php-fpm [14-Apr-2017 21:28:09] ERROR: unable to bind listening socket for address '127.0.0.1:9000': Address already in use (98)

[14-Apr-2017 21:28:09] ERROR: FPM initialization failed

failed

[root@redhat7 php-7.1.2]# netstat -nldp |grep 9000

tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 3721/php-fpm: maste

[root@redhat7 php-7.1.2]# kill 3721

[root@redhat7 php-7.1.2]# netstat -nldp |grep 9000

[root@redhat7 php-7.1.2]# /etc/init.d/php-fpm start

Starting php-fpm done

[root@redhat7 php-7.1.2]# service php-fpm status

php-fpm (pid 3927) is running...

[root@redhat7 php-7.1.2]# chkconfig --add php-fpm

[root@redhat7 php-7.1.2]# chkconfig php-fpm --level 345 on

配置nginx支持PHP

修改nginx的配置文件,支持php文件的解析,找到location的添加位置,在后面添加下面这个location

location ~ \.php$ {

root /usr/share/nginx/html; #指定php的根目录

fastcgi_pass 127.0.0.1:9000;#php-fpm的默认端口是9000

fastcgi_index index.php;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

include fastcgi_params;

}

展开
收起

PHP 7.3声称速度比PHP 5快3倍还多,值得更新了!

作为PHP5的最后一个版本,也是目前使用最广泛的PHP版本,PHP 5.6始于公元2014年(不是1804年,嘿嘿),其第一个测试版PHP 5.6 alpha 1版于2014年1月发布。随机产生了第一个由国人(鸟哥,惠新宸)参与主研的性能大规模提升版本PHPNG(PHP next generation,下一代PHP),2015年基于PHPNG接着就产生PHP 7版本。PHP7带来了革命性的性能提高,其运行速率是5.6的两倍还高以及其他改善,比如64位支持、类型申明、运行时优化等。从2015年开始官方就一直推荐大家尽快升级到php7,虽然当时扩展支持还是很成问题。

根据最新的W3techs统计,目前PHP 7大概占了超过16.6%的PHP份额。 总体上PHP仍然拥有大约83%的网站服务器端开发语言的绝大多数比例。

根据PHP开发支持周期,到今年12月31日后,PHP 5.6不在有官方支持。所以现在只剩下半年时间你升级你的PHP到PHP7。此后PHP5的命运就会终结,而且就虫虫所致目前基本上绝大多数的框架和程序都已经完美的支持PHP7了。

性能测试:PHP 7.3比PHP 7.0快25%

有很多性能测试对比都揭示了PHP 7比PHP 5.6快至少2倍。下面是各大php框架心性能对比图:

下面最新Phoronix基准测试结果则显示了自PHP7发布以来PHP 7的性能对比情况。最新版本的PHP 7.3 Alpha比以初始版本的PHP 7在系能上的改善的也是相当客观的。根据最新数据PHP 7.3是比PHP 5.6快3倍!比PHP 7.0快25%。不说别的光这性能对比图就能给烈日炎炎的夏日带来丝丝凉意。而且这还可以直接体现在费用上,比如升级PHP7后,Badoo大概每年可减少100w美刀。

Badoo公司的数据:

PHP 7兼容行检查

截止目前基本上绝大多数的PHP都可以完美的支持PHP7.0了。但是可能你恰好有一些历史遗留的脚本和程序,那么也好办,社区已经有好多的工具做兼容性检查,甚至给出直接的代码转译,以下是几个值得推荐的工具:

php7cc:一个很不错的工具,不过目前已经不再更新了。(github地址: /sstalle/php7cc)

php7mar:PHP 7迁移助手,虫虫强烈推荐的工具。 (github地址:/Alexia/php7mar)

使用方法:

php mar.php -f="/path/to/project/root/" -r="/path/to/output/"

phan:PHP脚本的静态分析器。 可以做当做php 7的语法检查器。(github地址:/phan/phan)

使用方法:phan --project-root-directory --progress-bar -o phan.out

phpstan - PHP静态分析和兼容性检查工具。(github地址:/phpstan/phpstan)

PHP 7性能设置要点

1. Opcache

首先,确保已经启用了OpCache。可以通过主配置文件php.ini或它独特的配置文件opcache.ini文件(例如/etc/php/7.2/fpm/conf.d/10-opcache.ini)。来进行设置。

zend_extension=opcache.so

opcache.enable=1

opcache.enable_cli=1

可以使用phpinfo()检查,也可以通过终端命令

php -v or php -i | grep opcache.enable

确认PHP OpCache已启用后,很多的ln(a)mp套件都有一个opCache监控脚本,可以对其系能进行实时监控,如下图

2、设置合适的realpath_cache_size

通过设置合宜的realpath_cache_size值可以改善你服务器的并发:

realpath_cache_size = 256k

realpath_cache_ttl = 300

3、禁止mysqlnd.collect_statistics

mysqlnd.collect_statistics = Off

mysqlnd.collect_memory_statistics = Off

线上服务器选择禁止这两个选项,可以减少不必要的数据库访问。如果需要相关统计,可以使用MySQL工具或者监控。

4、使用新的编译器

GCC 4.8编译器下编译时PHP才能开启Global Register for opline and execute_data支持, 这个会带来5%左右的性能提升。

5、开启Transparent HugePage (透传大页)

内存默认是以4KB分页的,而虚拟地址和内存地址需要转换,转化时候需要进行搜索,为了加速转换过程,可以通过内存TLB(Translation Lookaside Buffer)来。所以通过启用大内存页可以增加TLB 缓存命中,从而提高性能。

设置系统支持:

sysctl vm.nr_hugepages=512

php.ini 增加支持

opcache.huge_code_pages=1

关于这个值,很多实践后发现启用透传大页面后会带来系统负载过高,cpu占用过高问题,这时候通过关闭就可以解决。所以这个参数需要实际情况斟酌测试使用。

6、开启PGO

PHP是专门为一个项目服务,比如一个 Wordpress或者drupal站点,就可以使用PGO提高性能。

展开
收起

PHP7.3 正式发布

2018-12-06号,php7.3.0正式发布。

改动列表及新特性:

核心:

改进了PHP GC。重新设计了用PHP编写的旧的ext_skel程序,运行:'php ext_skel.php'获取所有选项。这意味着没有依赖关系,因此它可以在Windows上开箱即用。删除了对BeOS的支持。将PHP_VERSION添加到phpinfo()<title />。添加net_get_interfaces()。根据RFC https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes实现灵活的heredoc和nowdoc语法。根据RFC https://wiki.php.net/rfc/list_reference_assignment,添加了对list()和数组解构中的引用的支持。提高ZEND_SECURE_ZERO对NetBSD和没有本机类似功能的系统的有效性。添加了syslog.facility和syslog.ident INI条目,用于自定义syslog日志记录。修复了错误#75683(ZTS模式下zend_register_functions()中的内存泄漏)。修复了错误#75031(支持临时/内存流中的附加模式)。修正了错误#74860(当error_log设置为“syslog”时,未捕获的异常未正确格式化)。修复了错误#75220(在父级调用is_callable时的Segfault)。修正了错误#69954(分布式ini文件中已损坏的链接和未使用的配置项)。修复了错误#74922(组合类具有重复,相等的const属性的致命错误)。修复了错误#63911(相同的特征方法在编写过程中引发错误)。修复了错误#75677(Clang忽略了对可变参数函数的fastcall调用约定)。修复了错误#54043(删除了内部异常和用户定义异常的不一致)。修复了错误#53033(数学运算将对象转换为整数)。修复了错误#73108(内部类强制转换处理程序使用整数而不是浮点数)。修复了错误#75765(未找到基类时出现致命错误而非错误异常)。修复了错误#76198(措辞:“可迭代”不是标量类型)。修复了错误#76137(config.guess / config.sub无法识别RISC-V)。修复了#76427的错误(zend_objects_store_put中的Segfault)。修复了错误#76422(ftruncate文件> 2GB时失败)。修复了错误#76509(继承的静态属性可以通过ref从其父级取消同步)。修复了错误#76439(在未关闭的HereDoc中更改了行为)。修复了错误#63217(当用作ArrayAccess偏移时,常量数字字符串变为整数)。修复了错误#33502(某些nullary函数不检查参数的数量)。修复了错误#76392(错误重定位sapi / cli / php:不支持的重定位类型37)。不推荐使用不区分大小写的常量的声明和使用。为syslog过滤添加了syslog.filter INI条目。修正了错误#76667(Segfault with divide-assign op和__get + __set)。修复了错误#76030(RE2C_FLAGS很少被尊重)(CristianRodríguez)修复了损坏的zend_read_static_property(Laruence)修正了错误#76773(父类使用的特征会被子类忽略)。修正了错误#76767('asm'操作数在zend_operators.h中有不可能的约束)。修复了错误#76752(ZEND_COALESCE_SPEC_TMP_HANDLER崩溃 - _get_zval_ptr_tmp中的断言失败)。修复了#76820(Z_COPYABLE无效定义)的问题。修复了错误#76510(file_exists()停止为phar://工作)。修复了错误#76869(绕过受保护的方法accessibilty检查错误)。修正了错误#72635(constexpr中类常量使用的未定义类会产生致命错误)。修复了错误#76947(file_put_contents()阻止了文件的目录(__DIR__))。修复了错误#76979(define()错误消息未将资源视为有效值)。修复了错误#76825(未定义的符号___cpuid_count)。修复了#77110(C ++版本中未定义的符号zend_string_equal_val)。修正了#77231(使用convert.quoted-printable-encode过滤器时的Segfault)。bcmath时:

实施FR#67855(无法获得当前使用的规模)。修正了错误#66364(BCMath bcmul忽略了scale参数)。修复了错误#75164(split_bc_num()无意义)。修复了错误#75169(BCMath错误/警告绕过了PHP的错误处理)。CLI:

修复了错误#44217(stdout / stderr关闭后的输出导致立即退出状态为0)。修复了错误#77111(php-win.exe破坏了cli参数中的unicode符号)。BCMath:

将卷曲常数从卷曲7.50暴露到7.61。修复了错误#74125(修复了在支持多种支持的系统上查找CURL)。日期:

实现FR#74668:添加DateTime :: createFromImmutable()方法。修复了错误#75222(DateInterval微秒属性始终为0)。修复了错误#68406(在DateTimeZone对象上调用var_dump修改它)。修复了错误#76131(date_create的不匹配arginfo)。将timelib更新为2018.01RC1以解决几个错误:修复了错误#75577(DateTime :: createFromFormat不接受'v'格式说明符)。修复了错误#75642(微秒的环绕行为无法正常工作)。修正了错误#77097(当实际差异小于1秒时,DateTime :: diff会给出错误的差异)。DBA:

修复了错误#75264(发出编译器警告)。DOM:

修复了错误#76285(DOMDocument :: formatOutput属性有时会被忽略)。Fileinfo的:

修复了错误#77095(7.2 / 7.3中的慢速回归(与7.1相比))。过滤:

添加了'add_slashes'清理模式(FILTER_SANITIZE_ADD_SLASHES)。FPM:

添加了fpm_get_status函数。修复了错误#62596(PHP-FPM缺少getallheaders())。修复了错误#69031(进入stdout / stderr的长消息被错误截断) - 添加了与日志相关的新FPM配置选项:log_limit,log_buffering和decorate_workers_output。FTP:

修复了错误#77151(ftp_close():关机时的SSL_read)。GD:

在imagecreatefromstring()中添加了对WebP的支持。GMP:

导出GMP对象的内部结构和访问者助手。添加了gmp_binomial(n,k)。添加了gmp_lcm(a,b)。添加了gmp_perfect_power(a)。添加了gmp_kronecker(a,b)。的iconv:修复了错误#53891(iconv_mime_encode()无法对UTF-8字符串进行Q编码)。修正了错误#77147(修复60494忽略了ICONV_MIME_DECODE_CONTINUE_ON_ERROR)。IMAP:

修复了错误#77153(imap_open允许通过mailbox参数运行任意shell命令)。修复了错误#77020(imap_mail中的空指针取消引用)。Interbase的:修复了错误#75453(ibase_ [p]连接的反射错误)。修复了错误#76443(php + php_interbase.dll在module_shutdown上崩溃)。国际:

修复了错误#75317(UConverter :: setDestinationEncoding更改源而不是目标)。修复了错误#76829(对idn_to_utf8()函数的域验证不正确)。JSON:

添加了JSON_THROW_ON_ERROR标志。LDAP:

使用dds overlay为EXOP REFRESH操作添加了ldap_exop_refresh助手。添加了对发送和解析ldap控件的完全支持。修复了#49876(修复64位发行版上的LDAP路径查找)的问题。libxml2:

修复了错误#75871(使用pkg-config)。litespeed:

修复了错误#75248(仅构建litespeed SAPI时未创建二进制目录)。修复了错误#75251(缺少程序前缀和后缀)。MBstring:

更新为Oniguruma 6.9.0。修正了错误#65544(mb标题案例转换 - 引文中的第一个单词未大写)。修正了错误#71298(MB_CASE_TITLE行为错误,带有卷曲的撇号/引号)。修复了#73528的错误(zif_mb_send_mail崩溃)。修复了错误#74929(mbstring函数版本7.1.1与Windows上的5.3相比较慢)。修复了错误#76319(mb_strtolower与无效的UTF-8导致分段错误)。修复了错误#76574(使用未声明的标识符INT_MAX和LONG_MAX)。修复了#76594(由于zend_ini.c OnUpdateLong中的未对齐访问导致的总线错误)。修复了错误#76706(mbstring.http_output_conv_mimetypes被忽略)。修复了错误#76958(UTF7-IMAP转换损坏)。修复了#77025错误(mb_strpos抛出未知编码或转换错误)。修复了错误#77165(当给出一个空数组的参数时,mb_check_encoding崩溃)。Mysqlnd:

修复了错误#76386(Prepared Statement formatter截断日期/时间列的小数秒)。ODBC:

删除了对ODBCRouter的支持。删除了对Birdstep的支持。修复了#77079的错误(odbc_fetch_object有不正确的类型签名)。Opcache:

修复了错误#76466(循环变量混乱)。修复了错误#76463(var具有数组键类型但不是值类型)。修正了错误#76446(zend_variables.c:73:zend_string_destroy:断言`!(zval_gc_flags((str) - > gc))。修复了错误#76711(启用了OPcache触发误报“非法字符串偏移”)。修正了错误#77058(opcache中的类型推断会导致副作用)。修复了错误#77092(array_diff_key() - 分段错误)。OpenSSL:

添加了openssl_pkey_derive函数。添加min_proto_version和max_proto_version ssl流选项以及可能的TLS协议值的相关常量。PCRE:

实施https://wiki.php.net/rfc/pcre2-migration。将PCRE2升级到10.32。修正了错误#75355(preg_quote()没有引用#control字符)。修正了错误#76512(\ w不再包含unicode字符)。修复了错误#76514(preg_match中的回归使得它失败并出现PREG_JIT_STACKLIMIT_ERROR)。修复了错误#76909(preg_match在7.3和<7.3之间的差异)。PDO_DBlib:

实现FR#69592(允许自动跳过0列行集)。在\ PDO实例上将TDS版本公开为\ PDO :: DBLIB_ATTR_TDS_VERSION属性。像DATETIME一样处理DATETIME2列。修复了错误#74243(允许locales.conf驱动日期时间格式)。PDO_Firebird:

修复了错误#74462(对于FIREBIRD> = 3.0,布尔值为PDO_Firebird的结果只返回NULL)。PDO_OCI:

修正了错误#74631(PDO_PCO与PHP-FPM:在PHP-FPM设置之前初始化的OCI环境)。PDO SQLite:

添加对其他打开标志的支持pgSQL:

为pg_result_error()添加了新的错误常量:PGSQL_DIAG_SCHEMA_NAME,PGSQL_DIAG_TABLE_NAME,PGSQL_DIAG_COLUMN_NAME,PGSQL_DIAG_DATATYPE_NAME,PGSQL_DIAG_CONSTRAINT_NAME和PGSQL_DIAG_SEVERITY_NONLOCALIZED。修正了错误#77047(pg_convert的'TIME WITHOUT TIMEZONE'数据类型的正则表达式已损坏)。phar:

修复了错误#74991(include_path在某些情况下有4096个char限制)。修正了错误#65414(正确添加文件时处理前导斜杠)。修复了错误#77022(PharData始终使用模式0666创建新文件)。修复了phar_parse_pharfile中的错误#77143(堆缓冲区溢出(READ:4))。readline:

如果链接到libreadline,则为readline_info()添加completion_append_character和completion_suppress_append选项。Session:

修复了错误#74941(发送标头后会话无法启动)。SimpleXML:

修复了错误#54973(SimpleXML错误地转换了整数)。修复了错误#76712(空字符串的赋值创建了无关的文本节点)。插座:修复了错误#67619(在socket_write上验证长度)。肥皂:修复了错误#75464(对SoapClient :: __ setSoapHeaders的错误反映)。修正了错误#70469(即使使用例外= 1,SoapClient也会生成E_ERROR)。修复了错误#50675(SoapClient无法正确处理对象引用)。修复了错误#76348(WSDL_CACHE_MEMORY导致分段错误)。修复了错误#77141(当精度= -1时SOAP中的签名问题)。SPL:

修正了错误#74977(附加AppendIterator会导致段错误)。修复了错误#75173(AppendIterator :: append在foreach循环中的错误行为)。修复了#74372错误(带语法错误的自动加载文件使用下一个自动加载器,可能隐藏解析错误)。修复了错误#75878(RecursiveTreeIterator :: setPostfix有错误的签名)。修正了#74519(AppendIterator的奇怪行为)。修正了错误#76131(splarray构造函数的不匹配arginfo)。SQLite3:

将捆绑的libsqlite更新为3.24.0。Standard:

添加了is_countable()函数。添加了对SameSite cookie指令的支持,包括setcookie(),setrawcookie()和session_set_cookie_params()的替代签名。从inet_ntop()/ inet_pton()中删除多余的警告。修复了错误#75916(DNS_CAA记录结果包含垃圾)。修复了unserialize(),以通过手工制作的字符串禁用不受支持的数据结构的创建。修正了错误#75409(除了ENOSYS之外还接受EFAULT作为缺少getrandom()的指示)。修正了错误#74719(fopen()应该接受NULL作为上下文)。修复了错误#69948(路径/域未在setcookie中清理)。修复了错误#75996(mt_rand标头中的url不正确)。添加了hrtime()函数,以获得高分辨率时间。修复了错误#48016(尽管var_export()使用了stdClass :: __ setState,但未定义它)。修复了错误#76136(stream_socket_get_name应将IPv6括在括号中)。修复了错误#76688(禁止选项数组后的过多参数)。修复了错误#76713(属性损坏导致的分段错误)。修正了错误#76755(setcookie对于过期时间不接受“双重”类型)。修复了错误#76674(改进了array_ *失败消息,揭示了传递的内容而不是数组)。修复了错误#76803(ftruncate更改文件指针)。修复了#76818(内存损坏和段错误)的问题。修复了错误#77081(ftruncate()更改在c模式下搜索指针)。Testing:

实现了FR#62055(make run-tests.php支持--CGI--部分)。Tidy:

支持使用tidyp而不是整洁。修正了错误#74707(Tidy对于整理的函数有不正确的ReflectionFunction参数计数)。修复了tidy :: __ construct()的arginfo。Tokenizer:

修复了错误#76437(带有TOKEN_PARSE标志的token_get_all无法识别关闭标记)。修复了错误#75218(更改了解析为ParseError的剩余无法捕获的致命错误)。修复了错误#76538(带有TOKEN_PARSE标志的token_get_all无法识别带换行符的关闭标记)。修复了错误#76991(多个无效的灵活heredoc字符串的标记错误)。XML:

修复了错误#71592(外部实体处理从未失败)。zlib:

为compress.zlib包装器添加了zlib / level context选项。

展开
收起

php7.4候选版发布,性能又有了稳定提升

最近,万众期待的php7.4候选版本终于正式发布了。

接下来我们看看php7.4主要有哪些改进,以及在性能上有哪些提升。

首先,php7.4修复了大量的bugs,其中有些是内核的bug。

其次,这次发布的版本是所有新功能的增加的集合,也是锁定版,之后的正式版将不会增加新的功能,只会是修改bug和提升性能。

然后,php7.4的正式版发布日期也确定了下来,不出意外的话,会在2019年11月份发布。

接着,我们来说下php7.4带来了哪些新特性和改进。

新增加了FFI扩展功能,它可以让我们通过php代码,就可以直接访问c语言函数和变量以及结构体。GD库扩展新增加了TGA图片的支持SQLite3支持线上备份OpenSSL版本支持TLS1.3短闭包的支持预加载的支持自定义序列化改进类型差异简化Null合并运算符弃用短标签数组支持展开运算符

amd epyc php benchmarks

最后,我们看下php7.4的性能有怎样的提升。

下面是php7.4, php7.3, php7.2, php7.1, php7.0, php5.6的性能测试比较,测试环境是在debian系统下amd cpu环境下测试的。

php benchphp benchphp bench

从上面的测试结果我们可以看出来,虽然php7.4的性能提升相对来说很小,但是可以看出,在功能增加的情况下,性能依然在稳步提升。这些性能的提升,让我们很期待,也很坚信php8将会有更好的未来。

还有2个月php7.4就会正式发布,让我在接下来的日子来等待属于php的又一次辉煌的到来。

展开
收起

PHP7版本中有哪些新特性?

PHP7版本中的新特性有哪些?

一点PHP博客分享关于php7.0中的一些新特征,在PHP7中由于修改了底层引擎大部分代码,以及通过各种方式提高PHP的性能,所以在PHP7中也增加了一些新的语法,这些语法的使用也能对提高性能有帮助。

1.标量参数类型声明

现在支持字符串(string)、整型(int)、浮点数(float)、及布尔型(bool)参数声明,以前只支持类名、接口、数组及Callable两种风格:强制转换模式(默认)与严格模式

2.返回类型声明

3.??运算符

?? 用于替代需要isset的场合,这是一个语法糖。

4.<=> 比较运算符

就是看两个表达式值的大小,三种关系: = 返回0、< 返回-1、 > 返回 1

5.define支持定义数组类型的值

php 5.6已经支持CONST 语法定义数组类的常量,PHP7中支持define语法。

6.匿名类

7.增加了整除函数 intdiv

小结:

新特性

性能提升:PHP 7要比PHP 5.6快两倍,具体如何让PHP7中的性能达到最大化,可以看之前博主发的一篇文章。

全面一致的64位支持

移除了一些老的不在支持的SAPI(服务器端应用编程端口)和扩展

新增了空接合操作符(??)

如果觉得对你有帮助,请点点关注,也是对我的一种支持和鼓励,关注后查看更多内容。

不忘初心,继续编程。

展开
收起

PHP 7.1.27/7.2.16/7.3.3发布

IT之家3月8日消息 日前,PHP官方正式发布了PHP 7.1.27、PHP 7.2.16、PHP 7.3.3,这三个版本的PHP已经可以在PHP官网上下载。

根据官方给出的更新日志,PHP 7.2和7.3中主要修复了数据库连接方面的问题,而PHP 7.1则修复了几个空指针、内存溢出以及未初始化问题。

值得注意的是,PHP此前发文提醒还在使用PHP7.1以下的用户尽快升级,因为PHP 7.1以下版本已经在今年一月份停止支持,如果网站继续使用这些老版本的PHP很有可能遭受攻击。

目前,PHP官方支持三个版本,分别是PHP 7.1、PHP 7.2和PHP 7.3,而PHP 7.1也将在2019年12月1日停止支持。所以官方目前推荐用户向PHP 7.2以上版本迁移。

不过,现阶段PHP 7.0以下版本仍然占据了PHP网站的3/4以上,所以对于这部分用户来讲,尽快升级PHP 7.2以上版本非常有必要。

展开
收起

PHP7--PHP的一次重大变革

一、写在开头

PHP7是PHP编程语言全新的一个版本,主要在性能方面获得了极大的提升。官方的文档显示,PHP7可以达到PHP5.x版本两倍的性能。同时还对PHP的语法做了梳理,提供了很多其他语言流行的语法格式。难能可贵的是,做了如此大的改动,PHP7的兼容性还是非常好的。对于绝大多数的应用来讲,可以不用做修改即可迁移到PHP7版本。

PHP7你值得拥有

有人有疑问,为什么没有PHP6就直接PHP7了呢,实际上PHP6这个项目有过,只是后来取消了,但大量的功能已经在PHP5.x版本中得以实现。所以这一次直接就是PHP7。

二、PHP7的安装

使用编译安装太麻烦了,这里提供 Linux下的centos的安装php7的方法:

1)安装epel: yum -y install epel-release

2)更换rpm源,请根据自己的centos版本选择相应的rpm源进行安装:

Centos 5.X:

rpm -Uvhhttp://mirror.webtatic.com/yum/el5/latest.rpmCentOs6.x:

rpm -Uvhhttp://mirror.webtatic.com/yum/el6/latest.rpm

CentOs 7.X:

rpm -Uvhhttps://mirror.webtatic.com/yum/el7/epel-release.rpm

rpm -Uvhhttps://mirror.webtatic.com/yum/el7/webtatic-release.rpm

3)删除之前的php版本:

yum remove php * php-common

4)安装php7: yum install php70w

5)安装成功并检测: php -v

三、PHP7的新特性

1) 标量类型声明: PHP 7 中的函数的形参类型声明可以是标量了,即可以使用 string、int、float和 bool。

php7性能提升了2倍

2)NULL 合并运算符:

同时使用三元表达式和 isset()的情况,NULL 合并运算符使得变量存在且值不为NULL, 它就会返回自身的值,否则返回它的第二个操作数。

<?php// 如果 $_GET['user'] 不存在返回 'nobody',否则返回 $_GET['user'] 的值$username = $_GET['user'] ?? 'nobody';// 类似的三元运算符$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';?>4) 太空船操作符(组合比较符)

3)太空船操作符用于比较两个表达式。当$a大于、等于或小于$b时它分别返回-1、0或1。

// 整型echo 1 <=> 1; // 0echo 1 <=> 2; // -1echo 2 <=> 1; // 1

4)通过 define() 定义常量数组

define('ANIMALS', ['dog', 'cat', 'bird']);echo ANIMALS[1]; // 输出 "cat"?>

四、PHP7的修改

1.【 变量处理机制修改】:

间接变量、属性和方法引用都按照从左到右的顺序进行解释:

$$foo['bar']['baz'] // interpreted as ($$foo)['bar']['baz’]

如果想改变解释的顺序,可以使用大括号:${$foo['bar']['baz’]}

global关键字现在只能引用简单变量

global $$foo->bar; // 这种写法不支持。

global ${$foo->bar}; // 需用大括号来达到效果。

引用赋值时自动创建的数组元素或者对象属性顺序和以前不同了。

$array = [];$array["a"] =& $array["b"];$array["b"] = 1;var_dump($array);

PHP7产生的数组:["a" => 1, "b" => 1]

PHP5产生的数组:["b" => 1, "a" => 1]

2.【list()修改】

list()不再按照相反的顺序赋值

list($array[], $array[], $array[]) = [1, 2, 3];var_dump($array);上面的代码会返回一个数组:$array == [1, 2, 3] 而不是之前的 [3, 2, 1]

注意:只是赋值的顺序发生变化,赋的值还是和原来一样的。

空的list()赋值不再允许。

list() = $a;

list()不在支持字符串拆分功能

$string = "xy";

list($x, $y) = $string;

这段代码最终的结果是:$x == null and $y == null (不会有提示)

PHP5运行的结果是: $x = "x" and $y = "y”.

除此之外,list()现在也适用于数组对象:

list($a, $b) = (object) new ArrayObject([0, 1]);

PHP7结果:$a == 0 and $b == 1.

PHP5结果:$a == null and $b == null.

3.【 foreach 修改】

foreach()循环对数组内部指针不再起作用。

$array = [0, 1, 2];foreach ($array as &$val){var_dump(current($array));}

PHP7运行的结果会打印三次int(0),也就是说数组的内部指针并没有改变。

之前运行的结果会打印int(1), int(2)和bool(false)

按照值进行循环的时候,foreach是对该数组的拷贝操作

foreach按照值进行循环的时候(by-value),foreach是对该数组的一个拷贝进行操作。这样在循环过程中对数组做的修改是不会影响循环行为的。

$array = [0, 1, 2];$ref =& $array; // Necessary to trigger the old behaviorforeach ($array as $val) {var_dump($val); unset($array[1]);}

上面的代码虽然在循环中把数组的第二个元素unset掉,但PHP7还是会把三个元素打印出来:(0 1 2)

之前老版本的PHP会把1跳过,只打印(0 2).

按照引用进行循环的时候,对数组的修改会影响循环。

如果在循环的时候是引用的方式,对数组的修改会影响循环行为。不过PHP7版本优化了很多场景下面位置的维护。比如在循环时往数组中追加元素。

$array = [0];foreach ($array as &$val) {var_dump($val); $array[1] = 1;}

上面的代码中追加的元素也会参与循环,这样PHP7会打印"int(0) int(1)",老版本只会打印"int(0)”。

4.【参数处理机制修改】

重复参数命名不再支持

重复的参数命名不再支持。比如下面的代码执行的时候会报错:

public function foo($a, $b, $unused, $unused) {// ...}func_get_arg和func_get_args()调整

func_get_arg()和func_get_args()这两个方法返回参数当前的值,而不是传入时的值。当前的值有可能会被修改

function foo($x){$x++; var_dump(func_get_arg(0));}foo(1);

上面的代码会打印2, 而不是1。如果想打印原始的值,调用的顺序调整下即可。

同样在打印异常回溯信息的时候也是显示修改后的值。

function foo($x){$x = 42; throw new Exception;}foo("string");

PHP7的运行结果:Stack trace:

#0 file.php(4): foo(42)

#1 {main}

PHP5的运行结果:Stack trace:

#0 file.php(4): foo('string')

#1 {main}

这个调整不会影响代码的行为,不过在调试的时候需要注意这个变化。

其他和参数有关的函数都是同样的调整,比如debug_backtrace() .

五、如何升级当前项目代码来兼容PHP7?

逐步剔除php7不支持的代码

检测工具:https://github.com/sstalle/php7cc

检测不兼容PHP7的代码

六、写在最后

PHP7 2倍性能飙升,你心动了吗,赶紧下载代码运行吧~

附录:

php7官方文档:http://php.net/manual/zh/migration70.new-features.php

鸟哥的博客:http://www.laruence.com

展开
收起