PHP8 新特性
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 类型