欧易

欧易(OKX)

国内用户最喜爱的合约交易所

火币

火币(HTX )

全球知名的比特币交易所

币安

币安(Binance)

全球用户最多的交易所

PHP8的新功能展望:JIT以及其他

时间:2022-11-03 07:05:36 | 浏览:5905

万众瞩目的PHP 8,预计将于今年年12月份发布。根据已经批准和实施的RFC预案,可以PHP将带来许多强大的功能和出色的语言改进。作为尝鲜,让我们一起来展望一下PHP8的新功能和改进。PHP JIT(即时编译器)很多人可能已经了解,PHP

万众瞩目的PHP 8,预计将于今年年12月份发布。根据已经批准和实施的RFC预案,可以PHP将带来许多强大的功能和出色的语言改进。作为尝鲜,让我们一起来展望一下PHP8的新功能和改进。

PHP JIT(即时编译器)

很多人可能已经了解,PHP 8中最令人期望功能是JIT功能。在此我们先介绍一下JIT,根据PHP RFC提案:

"PHP JIT为Opcache部分的独立实现。它可以在PHP编译时和运行时启用/禁用。启用后,PHP文件的本机代码将存储在OPcache共享内存的附加区域中,并且op_array→o​​pcodes []。handler指针指向JIT版本代码的入口点。"

为了更好地理解什么是JIT for PHP,我review一下如何从源代码执行到最终结果。

PHP执行过程分为四个阶段:

Lexing/Tokenizing:解释器读取PHP代码并构建一组令牌。

语法解析:解释器检查脚本是否与语法规则匹配,并使用标记来构建抽象语法树(AST),AST是源代码结构的分层表示。

编译:解释器遍历树并将AST节点转换为低级Zend操作码,这些操作码是确定Zend VM执行的指令类型的数字标识符。

解释:操作码将在Zend VM上解释并运行。

基本PHP执行过程的直观表示如下:

那么,OPcache如何让PHP执行的更快?JIT执行过程中有哪些变化?

OPcache扩展

由于PHP是一种解释型语言,当运行PHP脚本时,解释器将在每次请求时都会重复地解析,编译和执行代码的过程。这会导致CPU浪费和其他资源耗费,让执行时间增加。

"OPcache通过将预编译的脚本字节码存储在共享内存中来提高PHP性能,从而消除了PHP在每个请求上加载和解析脚本的需要。"

启用OPcache后,PHP解释器仅在脚本首次运行时才进行4个阶段的过程。由于PHP字节码存储在共享内存中,因此可以作为低级中间表示形式缓存(OP)来被重复使用,可以立即在Zend VM上执行。

从PHP 5.5开始,Zend OPcache扩展在默认情况下启动,可以通过可以phpinfo()在Zend OPcache来查看Opcache配置情况。

预加载(Reload)

预加载是PHP 7.4新增的OPcache新功能。预加载提供了一种"在运行任何应用程序代码之前"将指定的脚本集存储到OPcache内存中的方法,但是对于典型的基于Web的应用程序而言,它不会带来明显的性能提升。

JIT —及时编译器

即使操作码采用低级中间表示码形式,仍然需要将其编译为机器代码。JIT"不引入任何其他IR(中间表示)形式",使用DynASM(用于代码生成引擎的动态汇编程序)直接从PHP字节码生成本机代码。

简而言之,JIT将中间码的热门部分转换为机器代码。绕过编译,它将能够显著的提高性能和内存使用率。

实时Web应用的JIT

根据JIT RFC,即时编译器实现应提高PHP性能。但是,我们真的会在WordPress等现实应用中体验到这种改进吗?

早期测试表明,JIT可以使CPU密集型工作负载的运行速度大大提高,但是对WordPress等应用并不能带来显著性能提高。

启用JIT后,代码将不会由Zend VM运行,而是由CPU本身运行,这将提高计算速度。诸如WordPress之类的Web应用程序还依赖于TTFB,数据库优化,HTTP请求等其他因素。

因此,当涉及到WordPress和类似的应用程序时,不应该期望PHP的执行速度会大大提高。但是,JIT可以为开发人员带来一些好处。


数字代码的性能明显更好。

"典型" PHP Web应用程序代码的性能略好。

将更多代码从C转移到PHP的潜力,因为PHP现在已经足够快了。"


因此,尽管JIT几乎不会给WordPress性能带来巨大的改善,但它将把PHP升级到一个新的水平,从而使它成为一种可以直接编写许多功能的语言。

不过,JIT的引入将会导致更大的复杂性,它可能导致维护,稳定性和调试成本增加。

PHP 8改进和新功能

除了JIT之外,还值得期望的PHP 8新功能和改进还有很多,它们将使PHP更加可靠和高效。

构造器属性增强

关于如何改进PHP中的对象人体工程学的持续讨论的结果是,构造器属性增强RFC提出了一种新的,更简洁的语法,该语法将简化属性声明,使其更短,更少冗余。

该提议仅与提升的参数有关,即以public,protected和private可见性关键字为前缀的那些方法参数。

目前所有属性必须重复几次(至少四次),然后才能将其与对象一起使用。下面是一个RFC的示例:

class Point {

public int $x;

public int $y;

public int $z;


public function __construct(

int $x = 0,

int $y = 0,

int $z = 0,

) {

$this->x = $x;

$this->y = $y;

$this->z = $z;

}

}

从PHP 8开始,将有一种更有用的声明参数的方法,上述代码可以简单写为:

class Point {

public function __construct(

public int $x = 0,

public int $y = 0,

public int $z = 0,

) {}

}

对比可以看出,新的属性语法更易读且不易出错。

抽象Trait方法验证

Trait是一种在单一继承语言中代码重用的机制。通常,它们用于声明可在多个类中使用的方法。

特征也可以包含抽象方法。这些方法只是声明方法的签名,但是方法的实现必须使用trait在类中完成。

trait T {

abstract public function test(int $x);

}

class C {

use T;

public function test(string $x) {}

}


如果实现方法与抽象特征方法不兼容,将会抛出致命错误:

Fatal error: Declaration of C::test(string $x) must be compatible with T::test(int $x) in /path/to/your/test.php on line 10

不兼容的方法签名

在PHP中,由于方法签名不兼容而导致的继承错误会引发致命错误或警告,具体取决于导致错误的原因。

如果类正在实现接口,则不兼容的方法签名将引发致命错误。根据对象接口文档:

实现接口的类必须使用与LSP(Liskov替换原理)兼容的方法签名。不这样做将导致致命错误。下面是一个带接口的继承错误的示例:

interface I {

public function method(array $a);

}

class C implements I {

public function method(int $a) {}

}

在PHP 7.4中,上面的代码将引发以下错误:

Fatal error: Declaration of C::method(int $a) must be compatible with I::method(array $a) in /path/to/your/test.php on line 7

子类中具有不兼容签名的函数将引发警告。

class C1 {

public function method(array $a) {}

}

class C2 extends C1 {

public function method(int $a) {}

}

在PHP 7.4中,上面的代码只会发出警告:

Warning: Declaration of C2::method(int $a) should be compatible with C1::method(array $a) in /path/to/your/test.php on line 7

在PHP 8,都会抛出致命错误。

Fatal error: Declaration of C2::method(int $a) must be compatible with C1::method(array $a) in /path/to/your/test.php on line 7

数组索引支持负数

在PHP中,如果数组以负索引(start_index < 0)开头,则以下索引自动从0开始。看下面的例子:

$a = array_fill(-5, 4, true);

var_dump($a);

在PHP 7.4中,结果如下:

array(4) {

[-5]=>

bool(true)

[0]=>

bool(true)

[1]=>

bool(true)

[2]=>

bool(true)

}

在PHP 8中,上面的代码将结果如下:

array(4) {

[-5]=>

bool(true)

[-4]=>

bool(true)

[-3]=>

bool(true)

[-2]=>

bool(true)

}

联合类型2.0

联合类型接受可以是不同类型的值。目前,PHP不支持联合类型,但?Type语法和特殊iterable类型除外。

在PHP 8之前,联合类型只能在phpdoc批注中指定:

class Number {

/**

* @var int|float $number

*/

private $number;


/**

* @param int|float $number

*/

public function setNumber($number) {

$this->number = $number;

}


/**

* @return int|float

*/

public function getNumber() {

return $this->number;

}

}

根据联合类型2.0 RFC提议在函数签名中添加对联合类型的支持,这样我们就不再依赖内联文档,而是使用T1|T2|...语法来定义联合类型:

class Number {

private int|float $number;


public function setNumber(int|float $number): void {

$this->number = $number;

}


public function getNumber(): int|float {

return $this->number;

}

}

联合类型支持所有可用类型,但有一些限制:

void类型不能是并集的一部分,因为void意味着函数不返回任何值。

null类型仅支持union的类型,但它的使用作为一个独立的类型是不允许的。

(?T)也可以使用可为null的类型表示法,表示T|null,但不允许在联合类型中包含该表示法(不允许使用?T1|T2,应该用T1|T2|null改用)。

尽可能多的功能(即strpos(),strstr(),substr()等等)包括false可能的返回类型中,false伪类型也支持。

内部函数的一致类型错误

传递非法类型的参数时,内部函数和用户定义函数的行为会有所不同。

用户定义的函数会引发TypeError,但是内部函数会根据多种情况以多种方式运行。无论如何,典型的行为是发出警告并返回null。比如下面的代码在PHP 7.4会导致告警

var_dump(strlen(new stdClass));

Warning: strlen() expects parameter 1 to be string, object given in /path/to/your/test.php on line 4

NULL

如果启用strict_types,或参数信息指定类型,则行为将有所不同。在这种情况下,将检测到类型错误并导致TypeError。

为了消除这些不一致之处,RFC建议使内部参数解析API在参数类型不匹配的情况下抛出ThrowError。

在PHP 8中,上面的代码将抛出致命错误:

Fatal error: Uncaught TypeError: strlen(): Argument #1 ($str) must be of type string, object given in /path/to/your/test.php:4

Stack trace:

#0 {main}

thrown in /path/to/your/test.php on line 4

抛出表表达式

在PHP中,throw是一个语句,因此无法在只允许使用表达式的地方使用它。

建议将throw语句转换为表达式,这样就可以在允许表达式的任何上下文中使用它。例如,箭头符号,空合并运算符,三元判断和合并运算符等:

$callable = fn() => throw new Exception();


// $value is non-nullable.

$value = $nullableValue ?? throw new InvalidArgumentException();


// $value is truthy.

$value = $falsableValue ?: throw new InvalidArgumentException();

WeakMap

WeakMap是弱引用键的数据(对象)的集合,这意味着不会阻止对它们的垃圾回收。

PHP 7.4添加了对弱引用的支持,以此作为保留对对象的引用的一种方式,这种引用不会阻止对象本身被破坏。

在长时间运行的进程中,这将防止内存泄漏并提高性能。:

$map = new WeakMap;

$obj = new stdClass;

$map[$obj] = 42;

var_dump($map);

使用PHP 8,上面的代码执行结果如下:

object(WeakMap)#1 (1) {

[0]=>

array(2) {

["key"]=>

object(stdClass)#2 (0) {

}

["value"]=>

int(42)

}

}

如果取消设置对象,则键会自动从弱Map中删除:

unset($obj);

var_dump($map);

现在的结果如下:

object(WeakMap)#1 (0) {

}

参数列表中的尾部逗号

尾随逗号是附加到不同上下文中的项目列表的逗号。PHP 7.2在列表语法中引入了结尾逗号,PHP 7.3在函数调用中引入了结尾逗号。

PHP 8现在在参数列表中以函数,方法和闭包形式引入尾部逗号,如以下示例所示:

class Foo {

public function __construct(

string $x,

int $y,

float $z,

) {

// do something

}

}

在对象上允许:: class语法

为了获取类的名称,可以使用FooBar::class语法。建议将相同的语法扩展到对象,以便现在可以获取给定对象的类的名称,如下例所示:

$object = new stdClass;

var_dump($object::class); // "stdClass"


$object = null;

var_dump($object::class); // TypeError

使用PHP 8,$object::class提供与相同的结果get_class($object)。如果$object不是对象,则抛出TypeError异常。

属性v2

属性,也称为注释,是结构化元数据的一种形式,可用于指定对象,元素或文件的属性。

在PHP 7.4之前,文档注释是将元数据添加到类,函数等的声明中的唯一方法。Attributes v2 RFC引入了PHP属性,这些属性将它们定义为结构化的语法元数据的形式,可以将其添加到类,属性,函数,方法,参数和常量。

将属性添加到它们所引用的声明之前。示例:

<<ExampleAttribute>>

class Foo

{

<<ExampleAttribute>>

public const FOO = "foo";


<<ExampleAttribute>>

public $x;


<<ExampleAttribute>>

public function foo(<<ExampleAttribute>> $bar) { }

}


$object = new <<ExampleAttribute>> class () { };


<<ExampleAttribute>>

function f1() { }


$f2 = <<ExampleAttribute>> function () { };


$f3 = <<ExampleAttribute>> fn () => 1;

可以在文档块注释之前或之后添加属性:

<<ExampleAttribute>>

/** docblock */

<<AnotherExampleAttribute>>

function foo() {}

每个声明可以具有一个或多个属性,并且每个属性可以具有一个或多个关联值:

<<WithoutArgument>>

<<SingleArgument(0)>>

<<FewArguments("Hello", "World")>>

function foo() {}

新的PHP函数

PHP 8为该语言带来了几个新功能,str_contains,str_starts_with(),str_ends_with()和get_debug_type

str_contains

在PHP 8之前,strstr和strpos是开发人员在给定字符串中搜索针的典型选择。问题是,这两个函数并不是很直观,它们的用法可能会使新人员感到困惑。

$mystring = "Managed WordPress Hosting";

$findme = "WordPress";

$pos = strpos($mystring, $findme);


if ($pos !== false) {

echo "The string has been found";

} else {

echo "String not found";

}

在上面的示例中,使用了!==比较运算符,该运算符还检查两个值是否属于同一类型。如果针的位置为0,这可以防止我们出错:

"此函数可能返回布尔FALSE,但也可能返回非布尔值,其值为FALSE。[…]使用===运算符测试此函数的返回值。"

此外,一些框架提供了帮助程序功能来搜索给定字符串内的值(比如Laravel)。

RFC建议引入一个新功能,该功能允许在字符串内部进行搜索:str_contains。

str_contains ( string $haystack , string $needle ) : bool

它的用法非常简单。str_contains检查是否$needle在中找到$haystack并返回true或false相应地返回。使用str_contains可以使用如下语法:

$mystring = "Managed WordPress Hosting";

$findme = "WordPress";


if (str_contains($mystring, $findme)) {

echo "The string has been found";

} else {

echo "String not found";

}

这更易读,更不容易出错。目前str_contains它区分大小写,但是将来可能会改变。

str_starts_with()和str_ends_with()

除此str_contains功能外,还有两个新功能允许在给定的规则搜索:str_starts_with和str_ends_with。检查给定字符串是否以另一个字符串开头或结尾:

str_starts_with (string $haystack , string $needle) : bool

str_ends_with (string $haystack , string $needle) : bool

如果$needle大于$haystack,则两个函数都将返回false。这两个函数都区分大小写:

$str = "WordPress";

if (str_starts_with($str, "Word")) echo "Found!";


if (str_starts_with($str, "word")) echo "Not found!";

get_debug_type

get_debug_type是一个新的PHP函数,它返回变量的类型。新函数的工作方式与gettype函数非常相似,但是get_debug_type返回本机类型名称并解析类名称。对于语言来说,这是一个很好的改进,gettype()对类型检查没有用。

RFC提供了两个有用的示例,可以更好地理解新get_debug_type()功能和的区别gettype()。第一个示例显示gettype了工作方式:

$bar = [1,2,3];

if (!($bar instanceof Foo)) {

throw new TypeError("Expected " . Foo::class . ", got " . (is_object($bar) ? get_class($bar) : gettype($bar)));

}

在PHP 8中,可以使用get_debug_type,而不是:

if (!($bar instanceof Foo)) {

throw new TypeError("Expected " . Foo::class . " got " . get_debug_type($bar));

}

下面显示了get_debug_type和gettype的返回值对比:

总结

在本文中,我们介绍了PHP 8发行版中预期的所有关键更改和改进。其中最值得期待的肯定是JIT编译器,还PHP 8还有很多其他功能。希望我们能早日运行新的版本,替换到满是bug的PHP 5.2系统(群里一个PHP 5.2老内存泄露,还不敢升级的人问怎么解决,有感!)。

相关资讯

PHP学习Thinkphp框架(1)——关于Thinkphp结构目录和数据库操作

Thinkphp:=> 简介:是由上海顶想公司开发的一款,PHP写成的,开源的MVC框架;官网:http://www.thinkphp.cn下载:https://github.com/top-think/framework 环境要求:

国产PHP框架ThinkPHP与SpeedPHP的浅析对比

本文主要简析两个国产的PHP框架ThinkPHP与SpeedPHP。通过学习发现,它俩在很多方面有着相似但又不同的地方:1.单一入口,二者都是单一入口文件。每个app都需要一个入口文件,且只能有一个入口文件。ThinkPHP生而就有多app

《PHP》什么是PHP框架,为什么要用PHP框架

PHP框架是什么?PHP框架提供了一个用以构建web应用的基本框架,从而简化了用PHP编写web应用程序的流程。这样不但节省开发时间,有助于建立更稳定的应用,而且减少了重复编码的开发。框架还可以帮助初学者建立更稳定的应用服务,这可以让你花更

「PHP发展史」PHP5.2到PHP5.6中新增的功能详解

截至目前(2014.2), PHP 的最新稳定版本是 PHP5.5, 但有差不多一半的用户仍在使用已经不在维护的 PHP5.2, 其余的一半用户在使用 PHP5.3。因为 PHP 那“集百家之长”的蛋疼语法,加上社区氛围不好,很多人对新版本

PHP8的新功能展望:JIT以及其他

万众瞩目的PHP 8,预计将于今年年12月份发布。根据已经批准和实施的RFC预案,可以PHP将带来许多强大的功能和出色的语言改进。作为尝鲜,让我们一起来展望一下PHP8的新功能和改进。PHP JIT(即时编译器)很多人可能已经了解,PHP

PHP开发者的福音,解读PHP异步通信框架Swoole的机制

在中国互联网行业膨胀的12-16年,PHP语言凭借自身易上手,开发周期短的优势,深受各中小企业的喜爱。小编也很荣幸在2009年底进入这一行业,为自己谋生分得一杯羹。但是PHP又先天有它的局限性,导致客户很多需求无法得到满足。大家都知道,P

ZWebPHP基于API的简易PHP开发框架

ZWebPHP 框架设计目的:标准化、体验统一、简单可靠、易于扩展后端PHP框架基于PHP、smarty 构建。基于composer自动加载。完全基于API接口设计,API文档自动生成。权限包含菜单访问权限和API接口访问权限。工具类、数据

PHP组件及框架推荐系列:PHP世界中最好的日志组件——Monolog

这也许,不,就是PHP世界中最好的日志组件—— Monolog所有的 PHPer,请站在巨人的肩膀上。随着 Composer 的普及,PHP 组件化开发思想越来越深入人心,我们没有必要重新自己打造轮子,只要确定需求和目标,设计好软件的架构,

「php框架教程」给PHP初学的你10个最常用的函数

PHP的功能越来越强大,里面有着非常丰富的内置函数。资深的PHP程序员对它们可能都很熟悉,但很多的PHP学习者,仍然对一些非常有用的函数不太熟悉。这篇文章里,我们就列举10个你或许不了解但实用的PHP函数,供大家参考和学习。1. php_c

纯PHP开发的高性能PHPsocket服务器框架

Workerman是一款纯PHP开发的开源高性能的PHP socket 服务器框架。被广泛的用于手机app、移动通讯,微信小程序,手游服务端、网络游戏、PHP聊天室、硬件通讯、智能家居、车联网、物联网等领域的开发。 支持TCP长连接,支持W

PHP框架开发-如何拥有自己的PHP框架

框架是帮助初学者创建稳定的程序。使得你可以花更多的时间去创造真正的Web程序,而不是编写重复性的代码。框架第一阶段什么是框架?一直以来php框架被广泛利用,多半都是基本mvc架构模式的,国内外框架有HDPHP框架、ThinkPHP、CI框架

可持续更新的PHP框架---是时候有自己的PHP框架了

怎样搭建自己一个PHP框架?PHP写了5年,不想用其他框架,想自己搭建一套mvc oop的框架 可以用别人一些类库,但核心orm 之类希望自己写。这是最近遇到了别人的一个问题,5年时间的PHP资深程序是可以独立开发出自己框架。小编今天带来H

PHP应用中比较好的php框架

PHP的框架很多,有phalcon,kohana ,laravel,Yii,thinkPHP,ROR,HD,,CI,和ROR等,我觉得PHP框架其实本身就是一个工具而已,没有好与不好,只有合不合适。任何东西都没有最好,只是不同的取舍。有人说

PHP框架之ThinkPHP框架

ThinkPHP框架人们习惯性又叫它TP框架,是一个轻量级的国产PHP开发框架,快速、兼容而且简单, ThinkPHP可以支持windows/Unix/Linux等服务器环境,正式版需要PHP5.0以上版本支持,支持MySql、PgSQL、

PHP框架的发展背景以及主流PHP框架横向对比

PHP框架的发展背景毫无疑问,Web框架技术在近几年已经得到了突飞猛进的发展和普及,在过去几年里,框架技术的普遍经历了比较大的完善过程,很大一部分可以归因于RubyonRails,以及在其他编程语言中流露出的MVC框架思想。如果你是一个PH

友情链接

网址导航 SEO域名抢注宝宝起名网妈妈知道币圈防晒霜品牌网TCL电视评测网母婴品牌网正品莆田鞋官网潜水运动飞鹤奶粉评测网卡丁车品牌网朝鲜旅游网小说阅读网金至尊珠宝海康威视股票沙漠探险苹果手机评测网新能源汽车网王者荣耀游戏网
钓鱼野钓网-钓鱼竿品牌十大排名、自制万能饵料、野钓小黑哥、钓鱼技巧大全调漂方法、钓鱼饵料配方、秋季鱼饵配方大全、钓鱼秘籍野钓技巧视频、野钓实用钓法中国台钓鼻祖三剑客、、野河钓鱼技巧大全、中国台钓鱼竿十大名牌排名。
钓鱼野钓网 5el.cn ©2022-2028版权所有