Jinyun's Notes

没什么天赋,爱好也不多,但愿坚持做些喜欢的事情

0%

PHP74 新特性

201911291254.png

PHP 7.4.0 提供了许多改进和新特性,比如:

有类型的类属性

类属性现在支持类型声明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

class User
{
public int $id;
public string $name;
}

$user = new User();
$user->id = '123';
$user->name = 123;

var_dump($user->id, $user->name);

// 结果
int(123)
string(3) "123"

箭头函数

箭头函数为使用隐式按值范围绑定定义函数提供了一种简写语法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

$factor = 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);

var_dump($nums);

// 结果
array(4) {
[0]=>
int(10)
[1]=>
int(20)
[2]=>
int(30)
[3]=>
int(40)
}

有限返回类型协变和参数类型逆变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php

class A
{
}

class B extends A
{
}

class Producer
{
public function method(): A
{
echo __METHOD__, PHP_EOL;

return new A();
}
}

class ChildProducer extends Producer
{
public function method(): B
{
echo __METHOD__, PHP_EOL;

return new B();
}
}

$producer = new Producer();
$childProducer = new ChildProducer();

if ($producer->method() instanceof A) {
var_dump('我特么就返回 A 的实例');
}
if ($childProducer->method() instanceof B) {
var_dump('我特么就返回 B 的实例');
}

// 结果
Producer::method
string(30) "我特么就返回 A 的实例"
ChildProducer::method
string(30) "我特么就返回 B 的实例"

Null 合并运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

function defaultValue(): string
{
return '';
}

$array = $_REQUEST;

// PHP74 之前

if (! isset($array['key'])) {
$array['key'] = defaultValue();
}

// PHP74 开始
$array['key'] ??= defaultValue();

// 虽然以下代码也可以,但是本人强烈反对这样写,不要问我为什么。代码块我总是用 {} 包起来
if (! isset($array['key'])) $array['key'] = defaultValue();

在数组内部展开元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];

var_dump($fruits);

// 结果
array(5) {
[0]=>
string(6) "banana"
[1]=>
string(6) "orange"
[2]=>
string(5) "apple"
[3]=>
string(4) "pear"
[4]=>
string(10) "watermelon"
}

数字字面量分隔符

人眼并未针对快速解析长数字序列进行优化。 因此,缺少视觉分隔符会使读取和调试代码花费更长的时间,并可能导致意外错误。

所以 数字字面量分隔符 就是解决人眼快速识别而做出的优化,你看,代码的的确确是机器去执行的,但更重要的是 可读、可写、可赏、可赞 😂。

1
2
3
4
5
6
7
8
9
10
11
12
6.674_083e-11; // float
299_792_458; // decimal
0xCAFE_F00D; // hexadecimal
0b0101_1111; // binary
0137_041; // octal

1_000_000; // versus 1000000
3.141_592; // versus 3.141592
0x02_56_12; // versus 0x025612
0b0010_1101; // versus 0b00101101
0267_3432; // versus 02673432
1_123.456_7e2 // versus 1123.4567e2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

usleep(345126); // without separator

usleep(345_126); // with separator

if (12345678989876 === 12345678998876) {
echo 'Equal';
} else {
echo 'Unequal';
}

echo PHP_EOL;

if (12_345_678_989_876 === 12_345_678_998_876) {
echo 'Equal';
} else {
echo 'Unequal';
}

弱引用

允许来自 toString() 的异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?php

class CustomException extends \Exception
{
}

class Foo
{
public function __toString()
{
throw new CustomException('Oops!');
}
}

$foo = new Foo();

try {
var_dump((string) $foo);
} catch (CustomException $e) {
var_dump($e);
}

// 结果

// PHP56
PHP Fatal error: Method Foo::__toString() must not throw an exception in /path/to/User.php on line 0

// PHP73
PHP Fatal error: Method Foo::__toString() must not throw an exception, caught CustomException: Oops! in /path/to/a.php on line 0

// PHP74
object(CustomException)#2 (7) {
["message":protected]=>
string(5) "Oops!"
["string":"Exception":private]=>
string(0) ""
["code":protected]=>
int(0)
["file":protected]=>
string(47) "/Users/xxx/Codes/example/untitled/User.php"
["line":protected]=>
int(11)
["trace":"Exception":private]=>
array(1) {
[0]=>
array(6) {
["file"]=>
string(47) "/Users/xxx/Codes/example/untitled/User.php"
["line"]=>
int(18)
["function"]=>
string(10) "__toString"
["class"]=>
string(3) "Foo"
["type"]=>
string(2) "->"
["args"]=>
array(0) {
}
}
}
["previous":"Exception":private]=>
NULL
}

Opcache 预加载

opcache.preload string:指定要在服务器启动时期进行编译和缓存的 PHP 脚本文件,这些文件也可能通过 include 或者 opcache_compile_file() 函数来预加载其他文件。所有这些文件中包含的实体,包括函数、类等,在服务器启动的时候就被加载和缓存,对于用户代码来讲是『开箱可用』的。

一些不推荐

Deprecated Features

从核心中移除的扩展

Removed Extensions

本笔记是笔者在学习和工作中的一些整理,如对您有用,请鼓励我继续写作