PHP7 新特性 (持续更新)

PHP

PHP 8 发布了,推荐查看:

PHP 8新特性


有一些明显的功能可以了解一下,稍微做个记录

PHP 7.4更新内容

箭头函数 2.0

RFC 简化了箭头函数

function array_values_from_keys($arr, $keys) {
return array_map(function ($x) use ($arr) { return $arr[$x]; }, $keys);
}

简化后:

function array_values_from_keys($arr, $keys) {
return array_map(fn($x) => $arr[$x], $keys);
}

注意:还是需要保留 fn 关键字

类型属性 2.0

RFC 现在可以在类中的 protected 属性值定义的值添加类型了(更像java这种强类型语言了)

<?php
class A
{
protected $Name
public function getName(){}
}

在PHP 7.4 之后:

<?php
class A
{
// 指定 $name 为字符类型
protected string $Name
public function getName(){}
}

Null 合并运算符

RFC

简单来说,就是 ?? 可以 ??= 来使用了

// 下面两种写法是一样的
$this->request->data['comments']['user_id'] = $this->request->data['comments']['user_id'] ?? 'value';
// 这是php7.4独有的写法
$this->request->data['comments']['user_id'] ??= 'value';

总结

肉眼可见的更新为以上这些,另外需要注意的是,这个版本弃用了很多东西,详细可以看这个列表:

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

其它一些:预加载/FFI/Covariant Returns and Contravariant Parameters 可以参考官方文档 https://www.php.net/ChangeLog-7.php#PHP_7_4

PHP 7.3

新增函数 array_key_first() array_key_last()

<?php
// 当 key 为字符串时
$array = ['a' => 1, 'b' => 2, 'c' => 3];
$firstKey = array_key_first($array);
$lastKey = array_key_last($array);
assert($firstKey === 'a'); // true
assert($lastKey === 'c'); // true
// 当 key 为数字时
$array = [1 => 'a', 2 => 'b', 3 => 'c'];
$firstKey = array_key_first($array);
$lastKey = array_key_last($array);
assert($firstKey === 1); // true
assert($lastKey === 3); // true
// 空数组
$array = [];
$firstKey = array_key_first($array);
$lastKey = array_key_last($array);
assert($firstKey === null); // true
assert($lastKey === null); // true

在函数调用中支持多个变量

$foo = 'hello';
$bar = 'php';
$baz = '!';
unset(
$foo,
$bar,
$baz,
);

更改日志

https://secure.php.net/ChangeLog-7.php#7.3.0

rfc

https://wiki.PHP.net/rfc#PHP_73

PHP 7.2

允许分组命名空间的尾部逗号

命名空间可以在 PHP 7 中使用尾随逗号进行分组引入。

<?php
use Foo\Bar\{
Foo,
Bar,
Baz,
};

其它

http://PHP.net/manual/zh/migration72.new-features.PHP

rfc

https://wiki.PHP.net/rfc#PHP_72

PHP 7.1

可为空(Nullable)类型

<?php
function testReturn(): ?string
{
return 'elePHPant';
}
var_dump(testReturn()); // string(10) "elePHPant"
function testReturn(): ?string
{
return null;
}
var_dump(testReturn()); // NULL
function test(?string $name)
{
var_dump($name);
}
test('elePHPant'); // string(10) "elePHPant"
test(null); // NULL
test(); // Uncaught Error: Too few arguments to function test(), 0 passed in...

其实是用 ? 号来代表函数参数与返回值要么为指定类型,要么为 null

Void 函数

一个新的返回值类型 void 被引入。 返回值声明为 void 类型的方法要么干脆省去 return 语句,要么使用一个空的 return 语句。 对于 void 函数来说,NULL 不是一个合法的返回值。

<?php
function swap(&$left, &$right) : void
{
if ($left === $right) {
return;
}
$tmp = $left;
$left = $right;
$right = $tmp;
}
$a = 1;
$b = 2;
var_dump(swap($a, $b), $a, $b);

以上结果输出

null
int(2)
int(1)

list 的方括号简写

短数组语法 [] 现在作为 list() 语法的一个备选项,可以用于将数组的值赋给一些变量(包括在 foreach 中)。

<?php
$data = [
[1, 'Tom'],
[2, 'Fred'],
];
// list() style
list($id1, $name1) = $data[0];
// [] style
[$id1, $name1] = $data[0];
// list() style
foreach ($data as list($id, $name)) {
// logic here with $id and $name
}
// [] style
foreach ($data as [$id, $name]) {
// logic here with $id and $name
}

list()现在支持键名

现在 list()和它的新的[]语法支持在它内部去指定键名。这意味着它可以将任意类型的数组 都赋值给一些变量(与短数组语法类似)

<?php
$data = [
["id" => 1, "name" => 'Tom'],
["id" => 2, "name" => 'Fred'],
];
// list() style
list("id" => $id1, "name" => $name1) = $data[0];
// [] style
["id" => $id1, "name" => $name1] = $data[0];
// list() style
foreach ($data as list("id" => $id, "name" => $name)) {
// logic here with $id and $name
}
// [] style
foreach ($data as ["id" => $id, "name" => $name]) {
// logic here with $id and $name
}

类常量可见性

现在起支持设置类常量的可见性。

<?php
class ConstDemo
{
const PUBLIC_CONST_A = 1;
public const PUBLIC_CONST_B = 2;
protected const PROTECTED_CONST = 3;
private const PRIVATE_CONST = 4;
}

支持为负的字符串偏移量

现在所有支持偏移量的字符串操作函数 都支持接受负数作为偏移量,包括通过[]或{}操作字符串下标。在这种情况下,一个负数的偏移量会被理解为一个从字符串结尾开始的偏移量。

<?php
var_dump("abcdef"[-2]); // string(1) "3"
var_dump(strpos("aabbcc", "b", -3)); // int(3)
<?php
$string = 'bar';
echo "The last character of '$string' is '$string[-1]'.\n";
//输出: The last character of 'bar' is 'r'.

其它

http://PHP.net/manual/zh/migration71.new-features.PHP

rfc

https://wiki.PHP.net/rfc#PHP_71

PHP 7.0

??运算符

这个比较常用,例子:

<?php
// PHP 7
$data = $_GET['type'] ?? '1';
// 等于
$data = isset($_GET['type']) ? $_GET['type'] : 1;

参数和函数返回值类型声明

<?php
// PHP 7
function sum(int $number) : int {
return $number + $number;
}
echo sum(1); // 2
// 等于
function sum($number){
return $number + $number;
}
echo sum(1); // 2

这种指定数据类型的方式可以避免一些 PHP 的隐式类型转换带来的问题,感觉是提供了一种强类型语言的选项吧。

PHP7 提供了一个严格模式, 配合严格模式用起来更好。 如果在非严格模式下返回了非指定类型,PHP 默认还是会进行隐式转换。比如:

<?php
// 非严格模式下
function sum(int $number) : int {
return $number + 1.8;
}
echo sum(1); // 2
// 等于
$data = 2.8;
echo (int)$data // 2

如果在严格模式下,返回非指定类型, PHP 则会报一个 PHP Fatal error 的错误。例如:

<?php
declare(strict_types=1);
function sum(int $number) : int
{
return $number + 1;
}
$a = sum(1.8);
print_r($a);

运行结果:

PHP Fatal error: Uncaught TypeError: Argument 1 passed to sum() must be of the type integer, float given, called in /path/Untitled 2.PHP:4
Stack trace:
...

use 批量声明

<?php
use App\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};

太空船操作符(组合比较符)

太空船操作符用于比较两个表达式。当$a 小于、等于或大于$b 时它分别返回-1、0 或 1。

<?php
// 整数
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
// 浮点数
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
// 字符串
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1

这个比较感觉没什么用

通过 define() 来定义常量数组

Array 类型的常量现在可以通过 define() 来定义。在 PHP5.6 中仅能通过 const 定义。

<?php
define('ANIMALS', [
'dog',
'cat',
'bird'
]);
echo ANIMALS[1]; // 输出 "cat"

生成器委托

现在,只需在最外层生成其中使用 yield from, 就可以把一个生成器自动委派给其他的生成器, Traversable 对象或者 array。

<?php
function gen()
{
yield 1;
yield 2;
yield from gen2();
}
function gen2()
{
yield 3;
yield 4;
}
foreach (gen() as $val)
{
echo $val, PHP_EOL;
}
// result
1
2
3
4

整数除法函数 intdiv()

新加的函数 intdiv() 用来进行整数的除法运算。

<?php
var_dump(intdiv(10, 3)); // int(3)

密码安全的伪随机数生成器 (CSPRNG) 函数

新加入两个跨平台的函数: random_bytes()random_int() 用来产生高安全级别的随机字符串和随机整数。

其它特性

http://PHP.net/manual/zh/migration70.new-features.PHP