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()方法允許跑出異常





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM