PHP7 的部分新特性


1. 運算符(NULL 合並運算符)

$a = $_GET['a'] ?? 1;

它相當於:

<php
$a = isset($_GET['a']) ? $_GET['a'] : 1;

我們知道三元運算符是可以這樣用的:

$a ?: 1

但是這是建立在 $a 已經定義了的前提上。新增的 ?? 運算符可以簡化判斷。

 

2、List 的方括號簡寫

PHP5.4 之前只能通過 array() 來定義數組,5.4之后添加了 [] 的簡化寫法。

<?php // 5.4 之前

$array = array(1, 2, 3);

$array = array("a" => 1, "b" => 2, "c" => 3);

// 5.4 及之后

$array = [1, 2, 3];

$array = ["a" => 1, "b" => 2, "c" => 3];

那么,如果要把數組的值賦值給不同的變量,可以通過 list 來實現:

  <?php list($a, $b, $c) = $array;

是否也可以通過 [] 的簡寫來實現呢?

  <?php [$a, $b, $c] = $array;

 以及下一個特性中會提到的 list 指定 key:

 <?php ["a" => $a, "b" => $b, "c" => $c] = $array;

 

PHP7.1 實現了這個特性,但:出現在左側的 [] 並不是數組的簡寫,而是 list() 的簡寫。

現在新的 list() 的實現並不僅僅可以出現在左值中,也能在 foreach 循環中使用: 

  <?php foreach ($points as ["x" => $x, "y" => $y]) {

      var_dump($x, $y);

  }

不過因為實現的問題,list() 和 [] 不能相互嵌套使用:

  <?php // 不合法

  list([$a, $b], [$c, $d]) = [[1, 2], [3, 4]];

  // 不合法

  [list($a, $b), list($c, $d)] = [[1, 2], [3, 4]];

  // 合法

  [[$a, $b], [$c, $d]] = [[1, 2], [3, 4]];

 

另外,在新的 list() 的實現中可以指定key:

  <?php $array = ["a" => 1, "b" => 2, "c" => 3];

  ["a" => $a, "b" => $b, "c" => $c] = $array;

相當於:

  <?php $a = $array['a'];

  $b = $array['b'];

  $c = $array['c'];

 

和以往的區別在於以往的 list() 的實現相當於 key 只能是 0, 1, 2, 3 的數字形式並且不能調整順序。執行語句:

  <?php list($a, $b) = [1 => '1', 2 => '2'];

會得到 PHP error: Undefined offset: 0... 的錯誤。

 

新的實現則可以通過以下方式來調整賦值:

   <?php list(1 => $a, 2 => $b) = [1 => '1', 2 => '2'];

不同於數組的是,list 並不支持混合形式的 key,以下寫法會觸發解析錯誤:

<?php // Parse error: syntax error, ...

list($unkeyed, "key" => $keyed) = $array;

 

更復雜的情況,list 也支持復合形式的解析:

<?php $points = [

    ["x" => 1, "y" => 2],

    ["x" => 2, "y" => 1]

];

 

list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = $points;

 

$points = [

    "first" => [1, 2],

    "second" => [2, 1]

];

 

list("first" => list($x1, $y1), "second" => list($x2, $y2)) = $points;

 

以及循環中使用:

<?php $points = [

    ["x" => 1, "y" => 2],

    ["x" => 2, "y" => 1]

];

 

foreach ($points as list("x" => $x, "y" => $y)) {

    echo "Point at ($x, $y)", PHP_EOL;

}

 

3. 標量類型和返回類型聲明(Scalar Type Declarations & Scalar Type Declarations)

PHP語言一個非常重要的特點就是“弱類型”,它讓PHP的程序變得非常容易編寫,新手接觸PHP能夠快速上手。PHP 7 中的函數的形參類型聲明可以是標量了。在 PHP 5 中只能是類名、接口、array 或者 callable (PHP 5.4,即可以是函數,包括匿名函數),現在也可以使用 string、int、float和 bool 了。支持變量類型的定義,可以說是革新性質的變化,PHP開始以可選的方式支持類型定義。除此之外,還引入了一個開關指令declare(strict_type=1);,當這個指令一旦開啟,將會強制當前文件下的程序遵循嚴格的函數傳參類型和返回類型。

例如一個add函數加上類型定義,可以寫成這樣:

如果配合強制類型開關指令,則可以變為這樣:

如果不開啟strict_type,PHP將會嘗試幫你轉換成要求的類型,而開啟之后,會改變PHP就不再做類型轉換,類型不匹配就會拋出錯誤。對於喜歡“強類型”語言的同學來說,這是一大福音。

需要注意的是嚴格模式的問題在這里同樣適用:強制模式(默認,既強制類型轉換)下還是會對不符合預期的參數進行強制類型轉換,嚴格模式下則觸發 TypeError 的致命錯誤。

 

4、 更多的Error變為可捕獲的Exception

 

PHP7實現了一個全局的throwable接口,原來的Exception和部分Error都實現了這個接口(interface), 以接口的方式定義了異常的繼承結構。於是,PHP7中更多的Error變為可捕獲的Exception返回給開發者,如果不進行捕獲則為Error,如果捕獲就變為一個可在程序內處理的Exception。這些可被捕獲的Error通常都是不會對程序造成致命傷害的Error,例如函數不存。PHP7進一步方便開發者處理,讓開發者對程序的掌控能力更強。因為在默認情況下,Error會直接導致程序中斷,而PHP7則提供捕獲並且處理的能力,讓程序繼續執行下去,為程序員提供更靈活的選擇。

 

例如,執行一個我們不確定是否存在的函數,PHP5兼容的做法是在函數被調用之前追加的判斷function_exist,而PHP7則支持捕獲Exception的處理方式。

5、AST(Abstract Syntax Tree,抽象語法樹)

    AST在PHP編譯過程作為一個中間件的角色,替換原來直接從解釋器吐出opcode的方式,讓解釋器(parser)和編譯器(compliler)解耦,可以減少一些Hack代碼,同時,讓實現更容易理解和可維護。

  PHP 5:

  

  PHP 7:

  

  更多AST信息:https://wiki.php.net/rfc/abstract_syntax_tree

6、其他新特性

PHP 7新特性和變化不少,我們這里並不全部展開來細說哈。

  1. Int64支持,統一不同平台下的整型長度,字符串和文件上傳都支持大於2GB。
  2. 統一變量語法(Uniform variable syntax)。
  3. foreach表現行為一致(Consistently foreach behaviors)
  4. 新的操作符 <=>, ??
  5. Unicode字符格式支持(\u{xxxxx})
  6. 匿名類支持(Anonymous Class)

 


免責聲明!

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



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