PHP 7系列版本(7.0、7.1、7.2、7.3、7.4)新特性

PHP很久不用了,很多新特性都记不清了,稍微整理一下。

  1. 标量参数类型声明[7.0]
  2. 返回值类型声明[7.0]
  3. Nullable类型[7.1]
  4. 属性值类型声明[7.4]
  5. Void 函数[7.1]
  6. 箭头函数[7.4]
  7. 类常量可见性[7.1]
  8. iterable 伪类[7.1]
  9. 新的object类型[7.2]
  10. 允许重写抽象方法[7.2]
  11. 类在实现接口方法时参数类型扩展[7.2]
  12. null合并运算符[7.0]
  13. 空值连写赋值运算符[7.4]
  14. 组合比较符[7.0]
  15. 通过 define() 定义常量数组[7.0]
  16. 支持匿名类[7.0]
  17. Unicode codepoint 转译语法[7.0]
  18. Closure::call()[7.0]
  19. 断言[7.0]
  20. use 分组写法[7.0]
  21. 允许分组命名空间的尾部逗号[7.2]
  22. 生成器可以返回表达式[7.0]
  23. 生成器委托[7.0]
  24. 可以使用 list() 函数来展开实现了 ArrayAccess 接口的对象[7.0]
  25. list()现在支持键名[7.1]
  26. 对称性数组解构[7.1]
  27. 数组的解构支持引用赋值[7.3]
  28. 多异常捕获处理[7.1]
  29. 支持为负的字符串偏移量[7.1]
  30. 通过名称加载扩展 dl()[7.2]
  31. 更灵活的Heredoc 与 Nowdoc 语法[7.3]
  32. Instanceof 运算符支持字面量[7.3]
  33. 允许函数和方法被调用时参数最后的空逗号收尾[7.3]
  34. 多字节字符串的相关函数[7.3]
  35. 数组内展开[7.4]
  36. 数值型字面量分隔符[7.4]
  37. 弱引用[7.4]
  38. __toString() 方法允许抛出异常[7.4]
PHP 7系列版本演化情况
新特性:








7.0
1、标量参数类型声明
标量类型声明 有两种模式: 强制 (默认) 和 严格模式。 

现在可以使用下列类型参数(无论用强制模式还是严格模式): 
字符串(string), 
整数 (int), 
浮点数 (float), 
以及布尔值 (bool)。

它们扩充了PHP5中引入的其他类型:类名,接口,数组和 回调类型。
<?php
// Coercive mode
function  sumOfInts ( int  ... $ints )
{
    return  array_sum ( $ints );
}

var_dump ( sumOfInts ( 2 '3' 4.1 ));

2、返回值类型声明
返回类型声明指明了函数返回值的类型。可用的类型与参数声明中可用的类型相同。
<?php

function  arraysSum (array ... $arrays ): array
{
    return  array_map (function(array  $array ):  int  {
        return  array_sum ( $array );
    },  $arrays );
}

print_r ( arraysSum ([ 1 , 2 , 3 ], [ 4 , 5 , 6 ], [ 7 , 8 , 9 ]));

3、null合并运算符
如果变量存在且值不为NULL, 它就会返回自身的值,否则返回它的第二个操作数。
<?php
// Fetches the value of $_GET['user'] and returns 'nobody'
// if it does not exist.
$username  $_GET [ 'user' ] ??  'nobody' ;
// This is equivalent to:
$username  = isset( $_GET [ 'user' ]) ?  $_GET [ 'user' ] :  'nobody' ;

// Coalesces can be chained: this will return the first
// defined value out of $_GET['user'], $_POST['user'], and
// 'nobody'.
$username  $_GET [ 'user' ] ??  $_POST [ 'user' ] ??  'nobody' ;
?>

4、太空船操作符(组合比较符)
用于比较两个表达式。当$a小于、等于或大于$b时它分别返回-1、0或1
<?php
// 整数
echo  <=>  1 // 0
echo  <=>  2 // -1
echo  <=>  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

5、通过 define() 定义常量数组
在 PHP5.6 中仅能通过 const 定义。
<?php
define ( 'ANIMALS' , [
     'dog' ,
     'cat' ,
     'bird'
]);

echo  ANIMALS [ 1 ];  // 输出 "cat"

6、匿名类

<?php
interface  Logger  {
    public function  log ( string $msg );
}

class  Application  {
    private  $logger ;

    public function  getLogger ():  Logger  {
         return  $this -> logger ;
    }

    public function  setLogger ( Logger $logger ) {
          $this -> logger  $logger ;
    }
}

$app  = new  Application ;
$app -> setLogger (new class implements  Logger  {
    public function  log ( string $msg ) {
        echo  $msg ;
    }
});

var_dump ( $app -> getLogger ());

7、Unicode codepoint 转译语法
接受一个以16进制形式的 Unicode codepoint,并打印出一个双引号或heredoc包围的 UTF-8 编码格式的字符串
echo "\u{aa}";
echo "\u{0000aa}";
echo "\u{9999}";

8、Closure::call()
简短干练的暂时绑定一个方法到对象上闭包并调用它。
<?php
class  {private  $x  1 ;}

// PHP 7 之前版本的代码
$getXCB  = function() {return  $this -> x ;};
$getX  $getXCB -> bindTo (new  A 'A' );  // 中间层闭包
echo  $getX ();

// PHP 7+ 及更高版本的代码
$getX  = function() {return  $this -> x ;};
echo  $getX -> call (new  A );

9、为unserialize()提供过滤
通过白名单的方式来防止潜在的代码注入。
<?php

// 将所有的对象都转换为 __PHP_Incomplete_Class 对象
$data  unserialize ( $foo , [ "allowed_classes"  =>  false ]);

// 将除 MyClass 和 MyClass2 之外的所有对象都转换为 __PHP_Incomplete_Class 对象
$data  unserialize ( $foo , [ "allowed_classes"  => [ "MyClass" "MyClass2" ]);

// 默认情况下所有的类都是可接受的,等同于省略第二个参数
$data  unserialize ( $foo , [ "allowed_classes"  =>  true ]);

10、断言
assert()现在是一个语言结构,它允许第一个参数是一个表达式,而不仅仅是一个待计算的 string或一个待测试的boolean。
<?php
ini_set ( 'assert.exception' 1 );

class  CustomError  extends  AssertionError  {}

assert ( false , new  CustomError ( 'Some error message' ));

11、Group use declarations
从同一 namespace 导入的类、函数和常量现在可以通过单个 use 语句 一次性导入了。
// PHP 7+ 及更高版本的代码
use  some \namespace\{ ClassA ClassB ClassC  as  C };
use function  some \namespace\{ fn_a fn_b fn_c };
use const  some \namespace\{ ConstA ConstB ConstC };

12、生成器可以返回表达式
允许在生成器函数中通过使用 return 语法来返回一个表达式 (但是不允许返回引用值), 可以通过调用 Generator::getReturn() 方法来获取生成器的返回值, 但是这个方法只能在生成器完成产生工作以后调用一次。
<?php

$gen  = (function() {
     yield 1 ;
     yield 2 ;

    return  3 ;
})();

foreach ( $gen  as  $val ) {
    echo  $val PHP_EOL ;
}

echo  $gen -> getReturn (),  PHP_EOL ;

13、生成器委托
只需在最外层生成器中使用 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 ;
}

14、整数除法函数 intdiv()
进行 整数的除法运算。
<?php

var_dump(intdiv(10, 3));

15、可以使用 list() 函数来展开实现了 ArrayAccess 接口的对象


7.1
1、Nullable类型
参数以及返回值的类型通过在类型前加上一个问号使之允许为空
<?php

function  testReturn (): ? string
{
    return  'elePHPant' ;
}

var_dump ( testReturn ());

function  testReturn (): ? string
{
    return  null ;
}

var_dump ( testReturn ());

function  test (? string $name )
{
     var_dump ( $name );
}

test ( 'elePHPant' );
test ( null );
test ();

2、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 );

3、对称性数组解构
短数组语法([])现在作为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
}

4、类常量可见性

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

5、iterable 伪类

<?php
function  iterator ( iterable $iter )
{
    foreach ( $iter  as  $val ) {
         //
     }
}

6、多异常捕获处理

<?php
try {
     // some code
} catch ( FirstException  SecondException $e ) {
     // handle first and second exceptions
}

7、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
}

8、支持为负的字符串偏移量
一个负数的偏移量会被理解为一个从字符串结尾开始的偏移量。
<?php
var_dump("abcdef"[-2]);
var_dump(strpos("aabbcc", "b", -3));
7.2
1、新的object类型
这种新的类型 object, 引进了可用于逆变(contravariant)参数输入和协变(covariant)返回任何对象类型。
<?php

function  test ( object $obj ) :  object
{
    return new  SplQueue ();
}

test (new  StdClass ());

2、通过名称加载扩展
使用 dl() 函数进行启用


3、允许重写抽象方法(Abstract method)

<?php

abstract class  A
{
    abstract function  test ( string $s );
}
abstract class  extends  A
{
     // overridden - still maintaining contravariance for parameters and covariance for return
     abstract function  test ( $s ) :  int ;
}

4、扩展了参数类型
重写方法和接口实现的参数类型现在可以省略了。不过这仍然是符合LSP,因为现在这种参数类型是逆变的。
<?php

interface  A
{
    public function  Test (array  $input );
}

class  implements  A
{
    public function  Test ( $input ){}  // type omitted for $input
}

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

<?php

use  Foo \ Bar \{
     Foo ,
     Bar ,
     Baz ,
};

6、更灵活的Heredoc 与 Nowdoc 语法



7、数组的解构支持引用赋值

  [&$a, [$b, &$c]] = $d

8、Instanceof 运算符支持字面量
判断结果总是  FALSE


9、允许函数和方法被调用时参数最后的空逗号收尾



10、多字节字符串的相关函数

mb_convert_case():
mb_strtolower())
mb_strtoupper())
<?php
mb_ereg ( '(?<word>\w+)' '国' $matches );
// => [0 => "国", 1 => "国", "word" => "国"];

<?php
mb_ereg_replace ( '\s*(?<word>\w+)\s*' "_\k<word>_\k'word'_" ' foo ' );
// => "_foo_foo_"


7.4
1、属性值类型声明

<?php
class  User  {
    public  int $id ;
    public  string $name ;
}

2、箭头函数

<?php
$factor  10 ;
$nums  array_map ( fn ( $n ) =>  $n  $factor , [ 1 2 3 4 ]);
// $nums = array(10, 20, 30, 40);

3、空值连写赋值运算符

<?php
$array [ 'key' ] ??=  computeDefault ();
// is roughly equivalent to
if (!isset( $array [ 'key' ])) {
     $array [ 'key' ] =  computeDefault ();
}

4、数组内展开

<?php
$parts  = [ 'apple' 'pear' ];
$fruits  = [ 'banana' 'orange' , ... $parts 'watermelon' ];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];

5、数值型字面量分隔符

<?php
6.674_083e - 11 // float
299_792_458 ;    // decimal
0xCAFE_F00D ;    // hexadecimal
0b0101_1111 ;    // binary

6、弱引用
引用对象使其不被销毁


7、__toString()方法允许跑出异常




猜你喜欢

转载自www.cnblogs.com/x3d/p/12975840.html