PHP 8.0正式发布:支持JIT编译器,性能提升高达3倍

美国时间11月26日,PHP团队宣布PHP 8.0正式GA。PHP 8.0是PHP语言的最新主要版本,带来了许多新特性和优化,包括命名参数(named arguments)、联合类型(union types)、属性(attributes)、构造器属性提升(constructor property promotion)、Match表达式、nullsafe运算符、JIT,以及针对类型系统、错误处理和一致性的诸多改进。

PHP 8.0.0 下载地址:

https://www.php.net/downloads

下文将对新版本的重要亮点做简单介绍:

https://wiki.php.net/rfc/named_params

PHP 7

PHP 8

  • 仅指定必需参数,跳过可选参数。
  • 参数与顺序无关,且是自描述的。

现在,开发者可以使用基于PHP原生语法的结构化元数据来代替PHPDoc注解。

https://wiki.php.net/rfc/attributes_v2

PHP 7

PHP 8

新版本定义和初始化属性所用的样板代码更少。

https://wiki.php.net/rfc/constructor_promotion

PHP 7

PHP 8

Union Types 支持接收多个不同类型的值,而不是单个类型。目前PHP已经支持两种特殊的联合类型:

  • Type或null,使用特殊?Type语法。
  • array或Traversable,使用特殊iterable类型。

对于类型组合,可以使用在运行时经过验证的原生联合类型声明来代替PHPDoc注解。

https://wiki.php.net/rfc/union_types_v2

支持联合类型之后,将会允许将更多类型信息从 phpdoc 迁移至函数签名。可以说,泛型之后,联合类型是目前类型声明系统中最大的突破口。

PHP 7

PHP 8

新的match很像switch,并具有以下特性:

  • Match是一个表达式,表示其结果可以存储在变量中或返回。
  • Match分支仅支持单行表达式,不需要break; 语句。
  • Match执行严格比较。

https://wiki.php.net/rfc/match_expression_v2

PHP 7

PHP 8

现在,开发者可以使用带有新的nullsafe运算符的调用链来代替null check。当对链中一个元素的求值失败时,整个链的执行将中止,并且整个链的求值为null。

https://wiki.php.net/rfc/nullsafe_operator

PHP 7

PHP 8

使用==和其他非严格比较运算符对字符串和数字之间做比较时,原本的做法是将字符串强制转换为数字,然后对整数或浮点数进行比较。这会导致许多令人惊讶的比较结果,其中最值得注意的是 0 == \”foobar\” 返回true。

在新版本中,仅在字符串实际为数字时才使用数字比较,否则将数字转换为字符串,并执行字符串比较。

https://wiki.php.net/rfc/string_to_number_comparison

PHP 7

PHP 8

在新版本中,如果参数验证失败,大多数内部函数将抛出Error异常。

https://wiki.php.net/rfc/consistent_type_errors

PHP 7

PHP 8

PHP 8引入了两个JIT编译引擎。Tracing JIT的表现最出色,它在综合基准测试中的性能提高到大约3倍,在某些特定的传统应用程序中提高到1.5–2倍。典型的应用程序性能与PHP 7.4相当。

JIT对PHP 8性能的贡献

  • 对算术/按位运算符进行更严格的类型检查(https://wiki.php.net/rfc/arithmetic_operator_type_checks)
  • 抽象特征方法验证(https://wiki.php.net/rfc/abstract_trait_method_validation)
  • 魔术方法的正确签名(https://wiki.php.net/rfc/magic-methods-signature)
  • 重分类引擎警告(https://wiki.php.net/rfc/engine_warnings)
  • 不兼容方法签名的致命错误(https://wiki.php.net/rfc/lsp_errors)
  • @运算符不再使致命错误静默。
  • 用私有方法继承(https://wiki.php.net/rfc/inheritance_private_methods)
  • 混合类型(https://wiki.php.net/rfc/mixed_type_v2)
  • 静态返回类型(https://wiki.php.net/rfc/static_return_type)
  • 内部函数类型(https://externals.io/message/106522)
  • 不透明的对象代替Curl、Gd、Sockets、OpenSSL、XMLWriter和XML扩展的资源
  • 在参数列表(https://wiki.php.net/rfc/trailing_comma_in_parameter_list)和使用闭包的列表(https://wiki.php.net/rfc/trailing_comma_in_closure_use_list)中允许结尾逗号
  • non-capturing捕获(https://wiki.php.net/rfc/non-capturing_catches)
  • 变量语法调整(https://wiki.php.net/rfc/variable_syntax_tweaks)
  • 将命名空间名称视为单个令牌(https://wiki.php.net/rfc/namespaced_names_as_token)
  • Throw现在是表达式(https://wiki.php.net/rfc/throw_expression)
  • 在对象上允许::class(https://wiki.php.net/rfc/class_name_literal_on_object)
  • Weak Map类(https://wiki.php.net/rfc/weak_maps)
  • Stringable接口(https://wiki.php.net/rfc/stringable)
  • str_contains()、str_starts_with()、str_ends_with()(https://wiki.php.net/rfc/str_contains)
  • fdiv()(https://github.com/php/php-src/pull/4769)
  • get_debug_type()(https://wiki.php.net/rfc/get_debug_type)
  • get_resource_id()(https://github.com/php/php-src/pull/54270
  • token_get_all()对象实现(https://wiki.php.net/rfc/token_as_object)

要下载PHP 8的源代码,请访问下载页面(https://www.php.net/downloads)。Windows二进制文件位于Windows版PHP网站(http://windows.php.net/download)。更改列表位于ChangeLog(http://www.php.net/ChangeLog-8.php)。

PHP手册中提供了迁移指南(https://www.php.net/manual/en/migration80.php)。请查阅它以获取新特性细节和向后不兼容更改的详细列表。

原文链接:https://www.php.net/releases/8.0/en.php

延伸阅读:

关注我并转发此篇文章,私信我“领取资料”,即可免费获得InfoQ价值4999元迷你书,点击文末「了解更多」,即可移步InfoQ官网,获取最新资讯~

作为世界上最好的语言——PHP 到底好在哪

在2020年12月26日,PHP 8.0.0 正式版发布了,伴随这圣诞节的钟声,PHP已走过了25个年头。作者我使用PHP也有7年有余,当然,我知道有这么一句话——PHP是世界上最好的语言这话半是称赞,半是揶揄,那么PHP到底好在哪。

先说结论:

  1. 万物皆 hashMap
  2. 热部署
  3. 和C/C++相似的语法
  4. 开箱即用的web环境
  5. 区别 字符拼接,算数+ 运算符

我用过C++, Java, PHP, Javascript,Python, , Go(排名就是我认识他们的顺序) 这些语言,对他们不敢说精通,也算了解,今天我主要谈谈PHP。

诞生2020年版号脚本语言热部署跨平台Web生态C++1983v20否否差一般Java1995v15否否好非常丰富NodeJS2009.5.28v15是否好非常丰富Python1991.12v3.9是否好丰富PHP1995.6.8v8是是好非常丰富Ruby1995v3是否好一枝独秀Groovy2007v4是是好一般Perl1987.12.18v5是否一般少C#2002.1v8否否差->一般一枝独秀Go2008v1.15否否好丰富

从从这个表格来看。 PHP也算是一门老语言了。基本和Java同样大了。可以看到 C++,Java,Node版本号很高,这侧面说明开发者对这门语言的热情,以及在这门语言上花的时间。而PHP中规中矩吧,在2021年初,PHP 正式版发布了 v8,PHP的使用者非常广泛,并且还诞生出一些类PHP语法的虚拟机——HHVM,以及能运行PHP的jvm。

也诞生出了很多PHP拓展来弥补性能短板——Opcache、Phalcon、swoole等。可以说PHP生态是百花齐放。

从语言排行榜来看:

排行榜参考:

https://www.tiobe.com/tiobe-index/www.tiobe.com

说说万物皆是——hashMap。在编码过程中,为了保存不同实体、对象,会用到数组,列表,对象,字典等。这些在PHP的底层实现以及的运用当中。一律用php array 来保存。使用过程中,phper不需要思考到底要用什么样的数据结构,用 list、dict、还是map,统统用 php array就行了,这使得phper心智负担小了很多,降低了上手门槛。当初我抱着《21天入门Java》时,看到容器一节,List、LinkedList、ArrayList、Set、Map、HashTable我都懵了,这都是啥。而PHP就是数组,作为小白用好数组就能干活了,当你需要用Map时,指定key就好了,当你需要用到Set时,array_unique就好了。概念简单,学习曲线平滑,当你需要深入时,你去看看array相关的函数就会有新的见解。

而透过PHP的源码,也可以看到array、k-v array、class 底层都是HashTable。这样的内存管理有点粗放(你都用脚本语言了,只要内存不泄露,内存管理粗放点也没啥),但使得PHP的底层数据结构显得单一简洁。相较于Python、Node这些脚本语言,PHP时在v7版本才从底层上引入Set、Map、Queue等数据结构,也不能说PHP没有数据结构、但想PHP这样的瑞士军刀般array,是其他语言少有的特性,这也是让我、以及很多phper对PHP这么语言难以格式的原因之一。

PHP Data Structures : 简介 – Manual​www.php.net

当我们在调试php-fpm程序的时候,改了代码,刷一下页面就能看到效果了。这样的简单直观的Debug体验,也是PHP独有的,编译性语言C/C++,Java 你得点一下rebuild 吧,当然你说有宇宙最强IDE的加持,改了代码自动编译,编译的时间也不断吧。在看看Python、Node,你不点个restart、也得等npm重新编译是不,这个在线debug效率就比php-fpm慢了不少。

试想一下作为一个编码初学者,这种快速、所见即所得的调试体验是非常棒的,你搞别的语言的,你还的配置一下IDE,或者改改package.json,作为代码初学者,哪知道什么叫断点调试,file watch,我就知道print(). (PS:很多PHPer写完一个function了,隔壁Javaer还在配置xml)。

好继续说热部署,这个是运维概念。就是线上PHP服务需要发布更新,只需要把代码复制粘贴上服务器就完事了。这种部署体验,随便找个实习运维都会,直接ftp就能搞定。要是Java、Node,Python这种,普通运维就是:1.代码打包,2.代码上传到线上,3.重启服务。如果是直接重启服务肯定会有中断时间,作为一个靠谱的运维,你得平滑重启。这一点就增加了很多工作成本。

当然这一切是有代价的,php-fpm的热部署是建立在重复编译之上的。随着这个计算机性能的提高,编译时间基本不再是系统的瓶颈。DB、IO反而是耗时大户。如果真要避免重复编译问题,使用php-cli模式也可以解决,用惯了php-fpm模式的我,换php-cli模式,调试的第一感觉就是慢。

php-fpm 框架,每次一次请求都是 compiler、init、 dispatch、 controller,会经可能优化这条流程。而php-cli 框架,compiler、 init 只会有一次,然后让每一次请求的 dispatch controller 很快很轻,这就会使得 init 这块 的逻辑做的比较重,所以改了代码重启会很慢。

我在大学入门编程语言就是C/C++,当我看到PHP时,除了没有 main 函数,变量多了个dollar符号,其他语法都差不多。画不多说之间看下语法对照表:

语法对照C/C++(区分大小写)PHP(变量区分大小写)变量赋值char a = \’a\’; /* 8位有符号*/int a=10; /* 16位有符号*/unsigned int a = 10; /* 16位无符号*/short a = 10; /* 16位有符号*/unsigned short a = 10;/* 16位无符号*/long a = 10; /* 32位有符号*/unsigned long a = 10; /* 32位无符号*/$i = 10; /* 变量以$开头*/$pi = 3.14;$a = \’a\’;$a = \’Hello!\’;if () {} else {}if (a == 12) … else {};if ($a == 23) … else {};switchswitch (expr){case expr1:DoSomething;break;case expr2:DoSomething;Break;case expr3:DoSomething;Break;default: exprN;}switch (expr){case expr1:DoSomething;break;case expr2:default: exprN;}forfor(expr1;expr2;expr3){DoSomething;}for(expr1;expr2;expr3){DoSomething;}foreachforeach($data as $key => $item) {doSometheing;}whilewhile(expr1){}while(expr1){}do {} while;do{}while(expr1);do{}while(expr1);函数int max(int num1, int num2) {// 局部变量声明int result = 2;return result; }function main() {return 0;}指针int var1;print(&var1);$a = 2;$b = &$a;类class Box{public:double length; // 盒子的长度double breadth; // 盒子的宽度privatedouble height; // 盒子的高度};class PhpClass {public $age;private $sex;public function getAge () {return $this->age;}}类属性、方法Box b = new Box();print(b.length);Box *b2 = &bprintf(b.breadth);$pc = new PhpClass();$pc->age;$pc->getAge();

以上表格参考自:

C、Delphi和PHP的基本语法对照表 – pchmonster – 博客园​www.cnblogs.com

PHP底层就是C写的,可以说学了C,再来看PHP,这不就是C的脚本语言么,在广大的C/C++大学入门教育的基础上,入手PHP时非常容易的。

我刚开始接触PHP时,没有尝试自己配置http代理,直接下载的集成环境——wamp,在windows上装好,PHP、Apache、MariaDB都能用了,写个

访问网页就能看到效果。

总之配置一套php开发环境是非常快的,配合Windows,双击exe、一路点点点就能搞定。如果你要写个Java还得配置下环境变量吧,还得了解下什么是环境变量。写C#,先下个几个G的宇宙最强IDE。这个时候入门的小白稍微遇到点阻力就有可能打退堂鼓,如果阻力多一点,我们又痛失一位程序员。

我估计有人要说Node和Python也是开箱即用,对,它们俩也不差。

再说下Serverless,最近炒的比较火的一个概念,我想说这不就是php-fpm。Serverless特点:

  1. 无需devops
  2. 无状态函数
  3. 动态扩容

无需devops,PHP基本上不怎么让运维操心,有问题重启,代码发布ftp,某段调试代码exit()写了忘了删, php-fpm不会全部死掉,这个进程死掉后会自动fork新的进程(当然你把exit写在index.php 第一行,那我可没法了啊)。

关于第2点,php-fpm 热部署特点就是。

第3点,如果你配置了 pm = dynamic,请求量大时php-fpm会自动fork更多子进程来处理请求,这就是动态扩容。

作为弱类型语言,大家都会遇到的问题。隔壁javascript 已经被这句代码搞得焦头烂额了。

而PHP直接将字符串拼接,与算数加,两个操作区分为两个语法。就完全避免了这个问题。

PHP的学习曲线平坦,让使用它的人一蹴而就。PHP的语法简单,数据结构单一,降低了使用者心智负担。PHP不失为我心中最好的语言。

原文链接:https://zhuanlan.zhihu.com/p/342838568

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。