文档章节

[译]PHP7简介:新特性与移除的特性

暗夜在火星
 暗夜在火星
发布于 2016/03/13 16:40
字数 4611
阅读 120
收藏 7
点赞 1
评论 0

[译]PHP7简介:新特性与移除的特性

/**
 * 原文出处:https://www.toptal.com/php/php-7-performance-features
 * @author dogstar.huang <chanzonghuang@gmail.com> 2016-03-13
 */

在PHP世界里,2015年最振奋人心的消息之一是PHP 7的版本发布,距离上一次主版本PHP 5长达10年之久。 向前迈进了巨大的一步后,PHP 7引入了大量的新特性以及性能升级。

然而,由于采用了一些兼容性中断,它把老的、弃用的功能也移除了,这使得老应用迁移到新版本更为困难。 如果你计划把已有的应用移到PHP 7之上或者构建新应用的话,此篇指南应该作为期待什么会发生的的快速向导。

但是等一等,PHP 6哪里去了?

如果近期你没在工作中一直使用PHP的话,你可能会疑惑PHP 6发生了什么,为什么会直接从PHP 5跳到PHP 7? 好吧,长话短说,PHP 6失败了。由于PHP主要用于网站开发而网站需要Unicode,版本6的主要特性是对于 Unicode的本地支持,所以把Unicode带到PHP这一举动是有意义的。

对此的想法就是把对于Unicode的完整支持带到本身的核心中去。这本来可以把扩展能力带到语言,从使用滑稽的emoji 作为变量和函数名字的能力,到强大的国际化字符功能。例如,当另一个有别于英文的语言使用大写和小写字符时, 或者当一个中文字符的名字需要转换成英语时。

PHP 6雄心勃勃,但很糟糕。这就是我们为什么在这个过程以PHP 7来结束,直接跳过6的原因。

不幸的是,雄心勃勃的计划证明是一个比预期还要大的问题。大部分的代码库需要移植以便在核心和重要扩展中都能支持Unicode, 这证明是繁琐而复杂的。这缓慢了语言中其他特性的开发进度,并在这个过程中使得很多PHP开发人员 感到沮丧。额外障碍的出现,让开发本地Unicode支持的兴趣大大减少,最终导致了这个项目被抛弃。

由于像书和文章这样的资源已经为PHP 6和它的Unicode支持编著好了,为了避免混淆新的版本将会命名为PHP 7。

不管怎样,往事不堪回首,让我们来看下PHP 7带来了什么。

性能之战,PHP 7 vs PHP 5

几乎所有的更新,轻微的性能升级是可以预期的。然而,这一次PHP带来了比以往早期的版本更重要的提升,使得纯粹性能成为了PHP 7 最吸引人的特性。这来自于“PHPNG”项目的一部分,这抓住了Zend Engine本身的内部结构。

通过重构内部数据结构和添加一个中间步骤到在抽象语法树(AST)表单的代码编译,结果是优越的性能和更高效的内存分配。 数字本身看起来来非常让人满怀希望:在真实世界应用完成的基准测试表明PHP 7平均比PHP 5.6快两倍,并且在请求期间减少了 50%的内存消耗,使得PHP 7成为了脸书 HHVM JIT 编译器强劲的对手。可以看下来自Zend为一些通用CMS和框架 描绘的图表信息。

PHP 7看起来和感觉都熟悉,但是它为性能作了调整。精制的Zend引擎和得到的结果性能产生了巨大的变化。

随着围绕PHP构建微服务的机遇,内存消耗的减少也使得更小的机器可以更好处理请求。内部的变化,尤其是AST实现,也打开了 可以把性能推向更远的未来优化的可能性。一个新的,在内部的JIT实现正在为未来的版本而被考虑。

PHP 7语法糖

伴随PHP 7而来的是新的语法特性。当没有在扩展语言本身的功能时,他们提供了一个更好的,或者更容易的方式让你的代码更令人愉悦 地编写以及看起来更畅心。

组导入声明

现在,我们可以把来源于相同命名空间的类组导入声明分组简化成use一行。这应该能在一种意义丰富的方式或简单地在文件中节 省一些字节帮助对齐声明。

use Framework\Module\Foo;
use Framework\Module\Bar;
use Framework\Module\Baz;

使用PHP 7我们可以使用:

use Framework\Module\{Foo, Bar, Baz};

或者,如果你更倾向多行的风格:

use Framework\Module{
    Foo,
    Bar,
    Baz
};

Null合并运算符

这解决了在PHP编程中一个通用的问题,就是我们想把一个变量的值赋给另一个变量时,如果后者实际上有设置的话,否则为它提供一个不同的值。 通常用于我们处理用户提供的输入时。

在PHP 7前

if (isset($foo)) {
    $bar = $foo;
} else {
    $bar = 'default'; // we would give $bar the value 'default' if $foo is NULL
}

PHP 7后

$bar = $foo ?? 'default';

也可以这样串联多个变量:

$bar = $foo ?? $baz ?? 'default';

飞船操作符

飞船操作符<=>允许有三种方式来比较两个值,不仅意味着如果他们相等,还包括哪一个更大,通过返回1,0或-1的不等式。

我们可以根据值的不同做出不同的动作:

switch ($bar <=> $foo) {
    case 0:
        echo '$bar and $foo are equal';
    case -1:
        echo '$foo is bigger';
    case 1:
        echo '$bar is bigger';
}

对比的值可以是整型int,浮点数float,字符串string甚至数组array。关于不同的值是如何相互对比的更多信息请查看文档:https://wiki.php.net/rfc/combined-comparison-operator

PHP 7中的新特性

当然PHP 7也带来了新的令人兴奋的功能。

标量参数类型 & 返回类型提示

通过添加这四个标量类型:;整型(int),浮点数(float),布尔值(bool)和字符串(string)和尽可能的参数类型, PHP 7扩展了先前在方法里(类,接口和数组)的参数类型声明。

更进一步,我们可以可选地指定方法和函数返回哪些类型。支持的类型有 bool,int,float,string,array,callable, 类名或接口名,self和parent(针对类方法)

class Calculator
{
    // We declare that the parameters provided are of type integer
    public function addTwoInts(int $x, int $y): int {
        return $x + $y; // We also explicitly say that this method will return an integer
    }
}

类型声明有助于构建更强壮的应用并且避免从函数传递或返回错误的值。其他好外包括静态代码分析和当缺少文档块时提供更好的代码库提示的IDE。

既然PHP是一个弱类型语言,参数和返回类型的值基于上下文投射。如果在一个函数中传递的值“3”并且声明参数类型为int,解释器会把它作为 一个整数来接收而不会抛出任何错误。如果你不想要这点,可以通过添加一个declare指示开启strict mode。

declare(strict_types=1);

这设置在每个文件的基础上,作为一个全局的选项划分代码库为和全局严格开启进行构建和全局严格开关关闭时构建,导致当我们从两者合并代码时出 现了非期望的行为。

引擎异常

通过添加的引擎异常,由脚本终端导致的致命错误可以轻松捕捉并处理。

例如调用一个不存在的方法的错误不会终止脚本,取而代之的是他们会抛出一个可以被try catch块处理的异常,这点提高了你应用的错误处理。 这对于诸如应用、服务和进程是重要的因为致命错误需要他们重新启动。在PHPUNit的测试也会变得更可用因为致命错误之前会丢掉整个测试套件。 异常,而不是错误,会在每一个测试案例基础上处理。

PHP 7看起来和感觉都熟悉,但是它为性能作了调整。精制的Zend引擎和得到的结果性能产生了巨大的变化。

PHP 7根据可能触发的错误类型添加了若干新的异常类。为了维护版本之间的兼容性,添加了一个新的接口Throwable,可以被引擎异常和用户异 常这两者实现。为了避免引擎异常扩展基础异常类这是有需要的,导致更老的代码捕捉当时还没有的异常。

在PHP 7前这样会以一个致命错误终止脚本:

try {
    thisFunctionDoesNotEvenExist();
} catch (\EngineException $e) {
    // Clean things up and log error
    echo $e->getMessage();
}

匿名类

匿名类是匿名函数的表兄弟,你可以在一个简短的实例中使用。匿名类创建简单并且像一个正常的对象那样使用即可。以下是来自文档的一个示例。

PHP 7前

class MyLogger {
  public function log($msg) {
    print_r($msg . "\n");
  }
}

$pusher->setLogger( new MyLogger() );

使用匿名类:

$pusher->setLogger(new class {
  public function log($msg) {
    print_r($msg . "\n");
  }
});

匿名类在单元测试中很有用,特别在模拟测试对象和服务时。这有利于我们通过创建一个简单的对象并提供我们想要模拟的接口来避免重量级的模拟库和框架。

CSPRNG函数

添加了两个生成加密安全字符串和整数的新函数。

random_bytes(int $len);

返回一个长度为$len的随机字符串。

random_int(int $min, int $max);

返回一个$min和$max之间的数字。

Unicode代码点转义语法

在PHP 7之前,不像其他很多语言,PHP没有一种转义字符语中Unicode代码点的方式。这个功能添加了序列\u以产生使用他们UTF-8代码点的字符。 这样相比直接插入字符更好,使得更好处理不可见的字符和有相同图表展示但意义不同的字符。

echo "\u{1F602}"; // outputs 😂‚

注意这会使用\u断开已有的代码因为它改变了行为。

生成器升级

在PHP的生成器也得到了一些优雅额外的特性。现在,生成器有一个可用于跟在迭代后允许输出一个最终值的返回声明。这点可用于检测生成器已经执行且没有错误 并且允许调用生成的代码处理大量适当的场景。

再进一步,生成器可以从其他生成器返回和yield表达式。这使得他们可以把复杂的操作划分为更简单和模块化的单元。

function genA() {
    yield 2;
    yield 3;
    yield 4;
}

function genB() {
    yield 1;
    yield from genA(); // 'genA' gets called here and iterated over
    yield 5;
    return 'success'; // This is a final result we can check later
}

foreach (genB() as $val) {
    echo "\n $val"; // This will output values 1 to 5 in order
}

$genB()->getReturn(); // This should return 'success' when there are no errors.

期望

期望是在维护向后兼容性时对assert()的一个增强。他们允许在生产代码中零消耗的断言,并提供当断言失败时抛出自定义异常的能力,这一点在开发中很有帮助。

assert()成为了PHP 7中的一个语言构造。 断言应该只在开发和测试环境中用于调试目的。为了配置它的行为,提供了两个新的标题给我们。


    • 1:生成并执行代码(开发模式)(默认值)

    • 0:生成代码但在运行时围绕它跳转

    • -1:不生成代码,零消耗(生产模式)


    • 1:当断言失败时抛出,通过抛出作为异常而提供的对象或者如果异常未提供时抛出一个新的 AssertionError 对象

    • 0:如上面描述一样使用或者生成一个 Throwable ,但只生成一个基于那个对象的警告而不是抛出它(兼容PHP 5)

准备好把PHP 5移到PHP 7

这次主发布的介绍带来了改变/升级老功能的一个机遇,或者甚至如果被认为过于古老或者已废弃有一段时间的话就移除他们。这样的改变会在老的应用引入兼容性的中断。

另外从这次版本跳跃而引发的一个问题是你所依赖的重要类库和框架可能还没升级到支持最新的版本。PHP团队已尝试着把这些新的改变尽可能向后兼容并且 让迁移到新版本尽可能少点痛苦。更新和更持续更新的应用可以发现转移到新版本更容易,而老的应用则不得不决定是否收益大于成本,并且可能选择不作升级。

大部分中断都是轻微的并且可以轻松迁移,而另外一些可能要更大的努力的更多的时间。基本上来讲,如果在安装PHP 7前在你的应用中警告,很可能会有中断应用直到修复的错误。 你有被警告过了,对吗?

老的SAPI和扩展

最重要地,诸如mysql扩展(但你应该不会在第一个地方使用这个,是吗?)这样老的和弃用的SAPI已被移除。完整的扩展和特性移除可以在这里这里查看这个RFC。

此外,其他的SAPI正在移植到PHP 7。

从PHP 7起很多老的SAPI和扩展已被丢弃。我们在想他们应该不会有人想起。

统一变量语法

这个更新为变量-变量结构的一致性做了一些修改。这允许了更先进带变量的表达式但也在其他一些场景中引入了变化,如下所示。

                        // old meaning            // new meaning
$$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']()

这会中断应用访问像这些变量的行为。另一方面,你可以做一些像这样奇妙的东西:

// Nested ()
foo()(); // Calls the return of foo()
$foo->bar()();

// IIFE syntax like JavaScript
(function() {
    // Function body
})();

// Nested ::
$foo::$bar::$baz

老风格标签的移除

<% ... %>,<%= ... %>,<script language="php"> ... </script>这类开/关标签已被移除并不再有效。用有效的替换这些很容易,但是你用这些来干嘛,怪咖?

类、接口和特征的无效名称

由于诸如参数和返回类型这样的附加项,类,接口和特征不再允许有以下名称:

  • bool

  • int

  • float

  • string

  • null

  • true

  • false

对于用到他们的已有应用和类库会引起中断,但修复很容易。同样,尽管不会引起任何错误并且是有效的,以下这些也不应该使用因为他们为将来使用而保留:

  • resource

  • object

  • mixed

  • numeric

克制使用他们能让你免于在未来再作调整。

对于会中断兼容的改变的完全列表,请查看这份文档

你也可以使用php7cc,它会检查你的代码并可以发现如果你转称到PHP 7可能会出来的任何潜在的问题。 但当然,没有比安装PHP 7并且自己亲自看一下更好的方式了。

潜在的PHP 7兼容性问题

PHP 7基础结构兼容性

大量托管的服务已开始着手添加对PHP 7的支持。这对于共享托管供应商是一个好消息,因为所得的性能允许他们在现有硬件提高网站客户数量, 降低运营费用,提高利润率。而对于客户端本身,他们期望在这样的条件下不应该有太大的提高,但出于公平而,无论如何共享托管不是一个面向性能的选择。

另一方面,提供虚拟私有服务商或专用服务商的服务会从这次性能跳跃中收益颇丰。一些支持PHP 7的PaaS服务如Heroku早期已上线,但其他的服务,像AWS Beanstalk 和Oracle’s OpenShift,正在滞后。检查你的PaaS供应商站点看下是否PHP 7已经被支持,或者是否即将支持。

当然,IaaS允许你掌控硬件和安装PHP 7(或者你喜欢也可以进行编译)。对于主流IaaS环境的PHP 7的包已经可用。

PHP 7软件兼容性

除了基础结构兼容性,你还需要留意潜在的软件兼容性问题。流行的内容管理系统(CMS)如WordPress,Joomla和Drupal已经在他们最新的版本吕添加了对PHP 7的支持。 主流的框架如Symfony和Laravel也已完善支持。

然而,是时候提到谨慎这个词了。此支持没有以附加组件,插件,包,或者不管你的CMS和框架如何调用他们的形式扩展到第三方代码。他们也许会在兼容性问题中 饱受折磨并且确保所有东西都已为PHP 7准备好是你的责任。

PHP的未来

PHP 7的发布移除了旧的、过时的代码并且为未来新特性和性能升级铺好了道路。所以,PHP有望很快得到更多的性能优化。尽管在过去发布中有一些兼容性中断, 大部分的问题都是很容易解决的。

类库和框架现在正迁移到他们的代码到PHP 7所以请获取最新的版本。我鼓励你去试一下并亲自看下结果。也许你的应该已经兼容并且等待使用,以及从PHP 7中受益。

参考:Before Debugging PHP That’s Not Working, Consult This List of the 10 Most Common Mistakes That PHP Developers Make


------------------------    



© 著作权归作者所有

共有 人打赏支持
暗夜在火星

暗夜在火星

粉丝 150
博文 150
码字总数 310930
作品 1
广州
程序员
swoole-1.8.0 发布,PHP 的异步并行 C 扩展

Swoole-1.8.0 版本已发布,此版本是一个里程碑式新版本,新增了多项新特性、多项核心功能优化以及问题修复、移除了无效的特性。更新内容如下: 客户端 增加原生异步 MySQL 客户端 增加原生异...

matyhtf ⋅ 2016/01/27 ⋅ 24

源码编译安装PHP7

2015年6月11日,PHP官网发布消息,正式公开发布PHP7第一版的alpha版本. PHP7特性: PHP 7.0.0 Alpha 1使用新版的ZendEngine引擎,带来了许多新的特性,以下是不完全列表: (1)性能提升:P...

王永濤 ⋅ 2015/06/23 ⋅ 0

简单快速的PHP MVC 框架--CodeIgniter 4

CodeIgniter 是什么? CodeIgniter 是一个简单快速的PHP MVC 框架。EllisLab 的工作人员发布了 CodeIgniter。许多企业尝试体验过所有 PHP MVC 框架之后,CodeIgniter 都成为赢家,主要是由于...

匿名 ⋅ 2017/03/31 ⋅ 1

PHP7新特性快速一览。

2015.12.3发生了两件大事,PHP7问世了,Swift开源了。 最好的语言发布了新的版本,一个划时代的大版本:PHP7。 PHP7修复了大量BUG,新增了功能和语法糖。这些改动涉及到了核心包、GD库、PDO...

李轩Lane ⋅ 2015/12/04 ⋅ 4

php7 新特性

标量类型声明 有两种模式: 强制 (默认) 和 严格模式。 现在可以使用下列类型参数(无论用强制模式还是严格模式): 字符串(string), 整数 (int), 浮点数 (float), 以及布尔值 (bool)。在旧版...

赵大财 ⋅ 2016/07/29 ⋅ 1

现货!《PHP7实践指南:o2o网站与App后台开发》京东天猫有售

终于发售了,啥也不想说了,喜欢的或需要的就点击 链接 进去购买吧。 另外此书将作为 2017 PHP全球开发者大会 现场活动用书 天猫购书 包邮 PHP7实践指南:O2O网站与App后台开发 数据库设计 PH...

szxy1234 ⋅ 2017/11/02 ⋅ 0

CmlPHP V2.5.1 发布,为程序员而生的开发框架

CmlPHP V2.5.1 发布,变更: Html模板引擎移除缓存文件头部换行 修复Html模板引擎中config 与 lang标签遇到带_的key值不识别的问题 开发文档增加锁-并发处理说明 主要特性: CmlPHP 基于php5....

雨空 ⋅ 2015/12/09 ⋅ 20

你的网站主机支持PHP7了吗?

如果要问企业建站采用哪种编程语言最为主流,那毫无疑问的当属PHP。单说流行程度,目前全球超过81.7%的服务器后端都采用了PHP语言,它驱动着全球绝大多数的网站。随着PHP7 的发布,很多主机空...

it1000001001 ⋅ 2017/03/07 ⋅ 0

蝉知建站系统PHP7性能测评

2015年底PHP7正式面世了,这是PHP语言发展史的一个重要里程碑,它带来了显著的性能提升和新特性,并对之前版本的一些特性进行了改进。今天我在虚拟机中分别搭建了相同环境LAMP,PHP版本分别是...

it1000001001 ⋅ 2017/03/06 ⋅ 0

PHP7飞船来了

闹眼子?这里说的飞船不是真的飞船,是被成为飞船符号(<=>)。 在PHP7,一个新的功能,飞船操作符已经被引入。它是用于比较两个表达式。当第一个表达式比第二个表达式分别小于,等于或大于它返...

hgditren ⋅ 2017/08/14 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

懒惰根本就不存在

简评:芝加哥大学心理学教授,懒惰根本就不存在。(本文表面讲行为心理学实则讲教育) 金句:以好奇而不是判断来回应一个人的无效行为,是非常有帮助的。 本文「我」代表原作者 E Price。 自...

极光推送 ⋅ 24分钟前 ⋅ 0

Excel提取单元格中最后一个“.”后面的数据

java.lang.String ----- String =TRIM((MID(SUBSTITUTE(B2,".",REPT(" ",99)),(LEN(B2)-LEN(SUBSTITUTE(B2,".","")))*99,99)))...

klog ⋅ 26分钟前 ⋅ 0

mac远程桌面

下载安装remote-desktop-mac Mac beta 客户端 mac通过远程桌面访问windows服务器。

亚林瓜子 ⋅ 31分钟前 ⋅ 0

firrtl

动手---sbt(2)之后,再回头看 chisel第一个实验,根据 https://github.com/freechipsproject/firrtl 发现firrtl没有执行sbt assembly命令,重新执行这个命令,结果成功。如下图: joe@joe-As...

whoisliang ⋅ 35分钟前 ⋅ 0

NIO

一、通道(Channel):用于源节点与目标节点的连接。在 Java NIO 中负责缓冲区中数据的传输。Channel 本身不存储数据,因此需要配合缓冲区进行传输。 二、通道的主要实现类 java.nio.channel...

stars永恒 ⋅ 35分钟前 ⋅ 0

Android悬浮窗的实现

0. 前言   现在很多应用都使用到悬浮窗,例如微信在视频的时候,点击Home键,视频小窗口仍然会在屏幕上显示。这个功能在很多情况下都非常有用。那么今天我们就来实现一下Android悬浮窗,以...

猴亮屏 ⋅ 36分钟前 ⋅ 0

日志采集中的关键技术分析

概述 日志从最初面向人类演变到现在的面向机器发生了巨大的变化。最初的日志主要的消费者是软件工程师,他们通过读取日志来排查问题,如今,大量机器日夜处理日志数据以生成可读性的报告以此...

tqyin ⋅ 37分钟前 ⋅ 0

使用Navicat将数据导出为text文本 然后再导入

将数据导出为text文本效率很高 1. 准备工作 1.1 准备表结构 1.2 目标库 执行生成表结构sql 2.将表数据导出为text文本 生成的text文本 3. 目标库 导入text 4.效果...

Lucky_Me ⋅ 43分钟前 ⋅ 0

IntelliJ IDEA 乱码解决方案 (项目代码、控制台等)

文章介绍了idea下,项目乱码、控制台乱码及运行tomcat控制台乱码的解决方案,文章链接:https://www.cnblogs.com/vhua/p/idea_1.html

Funcy1122 ⋅ 46分钟前 ⋅ 0

IDEA使用sonarLint

一、IDEA如何安装SonarLint插件 1.打开 Idea 2.点击【File】 3.点击【Settings】 4.点击【Plugins】 5.在搜索栏中输入“sonarlint”关键字 6.点击【Install】进行安装 7.重启Idea 二、IDEA如...

开源中国成都区源花 ⋅ 50分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部