1、JIT(Just in time)

PHP8增加了JIT,可以帮助弱语言通过直接编译为机器代码,而不是使用解释器执行,从而加快执行速度。

一图能解释清楚JIT是如何发挥作用的https://img2020.cnblogs.com/blog/925020/202011/925020-20201127231640082-819173287.png

很高兴的是加入JIT是一个好的开始,使得PHP有机会可以胜任做计算密集型的任务,使用范围将会扩大,更多开发人员能够使用到这么方便好用的语言。

但是弱类型的语言,决定了无法成为真正密集型计算的首选,看看想LUA PYTHON这样的语言,涉及到密集型计算,解决方案是更加方便的桥接C/C++语言,用底层语言模块来处理密集型计算。如果想更好的运转JIT,进一步提升PHP运行速度,就要像高级语言一样,指定变量的类型,也不能够变更变量的类型,对于array这种类型,也需要有数组和hash的区分,这样无形中也就丢失了PHP语言的优势了。

这就是有得有失吧,静看PHP JIT后续发展。

JIT不能提高有IO操作的应用速度,而web应用是PHP主战场,主要性能瓶颈在IO上,如果能像GO语言一样解决IO问题,对于web应用来说,就是性能大幅提升了。

2、命名参数

定义:
myFunction(paramName: $value);
array_foobar(array: $value);
使用:
array_fill(start_index: 0, count: 100, value: 50);
htmlspecialchars($string, double_encode: false);

位置参数和命名参数可以混合使用。

语法增强,对于代码理解和开发效率上会有所提升。

3、注解功能

通过 反射 API 可在运行时获取注解所定义的元数据。注解的目标可以是类、方法、函数、参数、属性、类常量。

定义:
<?php
// a.php
namespace MyExample;

use Attribute;

#[Attribute]
class MyAttribute
{
    const VALUE = 'value';

    private $value;

    public function __construct($value = null)
    {
        $this->value = $value;
    }
}

// b.php

namespace Another;

use MyExample\MyAttribute;

#[MyAttribute]
#[\MyExample\MyAttribute]
#[MyAttribute(1234)]
#[MyAttribute(value: 1234)]
#[MyAttribute(MyAttribute::VALUE)]
#[MyAttribute(array("key" => "value"))]
#[MyAttribute(100 + 200)]
class Thing
{
}

#[MyAttribute(1234), MyAttribute(5678)]
class AnotherThing
{
}
使用:
----------------------------------------
Function definition with attributes:
----------------------------------------
#[ReadOnly]
#[Property(type: 'function', name: 'Hello')]
function Hello()
{
    return "Hello";
}

-----------------------------------------
Gather attributes from the function
-----------------------------------------
function getAttributes(Reflector $reflection)
{
    $attributes = $reflection->getAttributes();
    $result = [];
    foreach ($attributes as $attribute)
    {
        $result[$attribute->getName()] = $attribute->getArguments();
    }
    return $result;
}

$reflection = new ReflectionFunction("Hello");
print_r(getAttributes($reflection));

-----------------------------
OUTPUT
-----------------------------
Array
(
    [ReadOnly] => Array
        (
        )

    [Property] => Array
        (
            [type] => function
            [name] => Hello
        )

)

注解做元编程,很多语言都有了,但使用反射API才可以使用,觉得有些怪,为啥不能让解释器来搞定这个事情呢?

同时还可以比较PHP的trait功能,同样类似,实现了多继承的能力,注解确实更方便,适用范围也扩大了。

4、构造器参数升级为属性

class Point {
    public function __construct(protected int $x, protected int $y = 0) {
    }
}

$x 和 $y 成为了Point类的属性,属性名称相同。语法,为了提升开发效率。

5、联合类型

变量可以定义类型的补充,毕竟PHP的变量以及参数及返回值,之前大部分都是多种类型的。联合类型可以包含可能的类型,同时也检测不在联合类型范围内的错误类型。

function foo(): int|INT {} // 不允许
function foo(): bool|false {} // 不允许

use A as B;
function foo(): A|B {} // 不允许 ("use" 是名称解析的一部分)

class_alias('X', 'Y');
function foo(): X|Y {} // 允许 (运行时才能知道重复性)

5、match表达式

function days_in_month(string $month): int
{
    return match(strtolower(substr($name, 0, 3))) {
        'jan' => 31,
        'feb' => is_leap($year) ? 29 : 28,
        'mar' => 31,
        'apr' => 30,
        'may' => 31,
        'jun' => 30,
        'jul' => 31,
        'aug' => 31,
        'sep' => 30,
        'oct' => 31,
        'nov' => 30,
        'dec' => 31,
        default => throw new InvalidArgumentException("Bogus month"),
    };
}

函数式编程中重要的功能,这里是switch功能的加强版,很好用。

6、Nullsafe方法和属性

// 自 PHP 8.0.0 起可用
$result = $repository?->getUser(5)?->name;

// 上边那行代码等价于以下代码
if (is_null($repository)) {
    $result = null;
} else {
    $user = $repository->getUser(5);
    if (is_null($user)) {
        $result = null;
    } else {
        $result = $user->name;
    }
}

在好多语言中也有看到过,非常方便,但应该有个方法可以防止或者能够处理为null的情况。

7、一些有意思的改进

1)只要类型兼容,任意数量的函数参数都可以用一个可变参数替换

class A {
     public function method(int $many, string $parameters, $here) {}
}
class B extends A {
     public function method(...$everything) {}
}

2)static (“后期静态绑定”中) 可以作为返回类型

class Test {
     public function create(): static {
          return new static();
     }
}

3)现在可以通过 $object::class 获取类名,返回的结果和 get_class($object) 一致

4)Trait 可以定义私有抽象方法(abstract private method)。 类必须实现 trait 定义的该方法。

5)可作为表达式使用 throw

$fn = fn() => throw new Exception('Exception in arrow function');
$user = $session->user ?? throw new Exception('Must have user');

6)参数列表中的末尾逗号为可选

function functionWithLongSignature(
    Type1 $parameter1,
    Type2 $parameter2, // <-- 这个逗号也被允许了
) {
}

7)现在允许 catch (Exception) 一个 exception 而无需捕获到变量中

8)支持 mixed 类型

8、其余就是一些库函数的改进了,可在变更日志中查看

https://www.php.net/manual/zh/migration80.new-features.php

发表评论

邮箱地址不会被公开。 必填项已用*标注