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新特性和變化不少,我們這里並不全部展開來細說哈。
- Int64支持,統一不同平台下的整型長度,字符串和文件上傳都支持大於2GB。
- 統一變量語法(Uniform variable syntax)。
- foreach表現行為一致(Consistently foreach behaviors)
- 新的操作符 <=>, ??
- Unicode字符格式支持(\u{xxxxx})
- 匿名類支持(Anonymous Class)
