PHP 7.2 新功能介紹

clipboard.png

PHP 7.2 已經在 2017 年 11 月 30 日 正式發布 。這次發布包含新特性、功能,及優化,以讓我們寫出更好的代碼。在這篇文章裡,我將會介紹一些 PHP 7.2 最有趣的語言特性。php

你能夠在 Requests For Comments 頁面查看完整的更動清單。html

核心改進

參數類型聲明

從 PHP5 起,咱們能夠指定函數參數的預期聲明類型。若是傳參類型錯誤,PHP 就會拋出一個錯誤。laravel

參數類型聲明 (也稱類型提示) 指定預期要傳參給函數或者類方法的參數類型。

這裏有個例子:git

class MyClass {
    public $var = 'Hello World';
}

$myclass = new MyClass;

function test(MyClass $myclass){
    return $myclass->var;
}

echo test($myclass);

在這段代碼中,測試函數須要一個 MyClass 實例。不正確的參數數據類型會致使一個致命錯誤。算法

Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of MyClass, string given, called in /app/index.php on line 12 and defined in /app/index.php:8

從 PHP 7.2 類型提示 能夠被用在對象型數據上,而且這個改進容許通用對象類型做爲一個函數或者方法的參數。這裏有個例子:docker

class MyClass {
    public $var = '';
}

class FirstChild extends MyClass {
    public $var = 'My name is Jim';
}
class SecondChild extends MyClass {
    public $var = 'My name is John';
}

$firstchild = new FirstChild;
$secondchild = new SecondChild;

function test(object $arg) {
    return $arg->var;
}

echo test($firstchild);

echo test($secondchild);

在以上示例中,咱們調用了兩次測試函數,每次都傳遞一個不一樣的對象。這在以前的 PHP 版本中是史無前例的。編程

file

在 Docker 中測試 PHP 7.0 和 PHP 7.2 的類型提示。c#

對象返回類型聲明

若變量類型指定函數參數的預期類型,返回值類型一樣也能夠被指定預期類型。數組

返回類型聲明 指定一個函數應該返回的預期類型。

PHP 7.2 起,對象數據類型可使用返回類型聲明。這裏有個例子:安全

class MyClass {
    public $var = 'Hello World';
}

$myclass = new MyClass;

function test(MyClass $arg) : object {
    return $arg;
}

echo test($myclass)->var;

以前的 PHP 版本會拋出如下致命錯誤:

Fatal error: Uncaught TypeError: Return value of test() must be an instance of object, instance of MyClass returned in /app/index.php:10

固然,PHP 7.2 的代碼會打印出 'Hello World'。

參數類型泛化

PHP 目前是不容許子類和它父類或者接口的參數類型有任何差別的。 這是什麼意思呢?
參考下如下代碼:

<?php
class MyClass {
    public function myFunction(array $myarray) { /* ... */ }
}

class MyChildClass extends MyClass {
    public function myFunction($myarray) { /* ... */ }
}

這裏咱們省略了子類中的參數類型。 在 PHP 7.0 中,會產生如下警告:

Warning: Declaration of MyChildClass::myFunction($myarray) should be compatible with MyClass::myFunction(array $myarray) in %s on line 8

從 PHP 7.2 起,咱們能夠忽略子類中的類型 而不會破壞任何代碼。這個方案使得咱們能夠在庫中升級類,從而可使用類型提示,卻無需更新其全部的子類。

列表語法中的尾隨逗號

在 PHP 數組的最後一個元素上使用尾隨逗號是 合法語法 ,而且 有時候鼓勵這麼作 ,能夠很輕鬆的避免增長新元素的時候出現缺失逗號的錯誤。 從 PHP 7.2 在 分組命名空間 中,咱們可使用尾隨逗號 。

參閱 列表語法中的尾隨逗號 得到 RFC 的直觀感知和一些示例代碼。

安全性改進

密碼哈希中的Argon2

Argon2 是榮獲 2015 年密碼哈希算法比賽中的冠軍的強大哈希算法, PHP 7.2 將其做爲安全  Bcrypt 算法的替代品。
新版的 PHP 中引入了 PASSWORD_ARGON2I 常量,如今能夠在 password_* 系列函數中使用:

password_hash('password', PASSWORD_ARGON2I);

與只使用一個 cost 因子的 Bcrypt 不一樣, Argon2 使用三個 cost 因子 區分以下:

  • 定義哈希計算期間應該消耗的KiB數量的內存開銷(默認值爲1 << 10或1024 KiB或1 MiB)
  • 定義哈希算法迭代次數的時間開銷(默認值爲2)
  • 並行因子,用於設置哈希計算時使用的並行線程數(缺省值爲2)

如下三個新常量定義了默認的 cost 因子:

  • PASSWORD_ARGON2_DEFAULT_MEMORY_COST
  • PASSWORD_ARGON2_DEFAULT_TIME_COST
  • PASSWORD_ARGON2_DEFAULT_THREADS

這裏有個例子:

$options = ['memory_cost' => 1<<11, 'time_cost' => 4, 'threads' => 2];
password_hash('password', PASSWORD_ARGON2I, $options);

查閱 Argon2 密碼哈希 的更多信息。

Libsodium 成爲 PHP 核心的組成部分

從 7.2 版開始,PHP 在其核心中涵蓋了 Sodium library 。 Libsodium 是一個跨平臺和跨語言的庫,用於加密,解密,簽名,密碼哈希等。
這個庫以前是 經過 PECL 來提供的。
有關 Libsodium 函數列表,參閱 快速入門
也可參閱 PHP 7.2: 第一個將現代加密技術添加到其標準庫的編程語言

棄用

這裏有個 PHP 7.2 棄用函數和特性 清單,PHP 8.0 以後將所有移除。

PHP 5.1 中 __autoload 函數已被 spl_autoload_register 取代。如今會在編譯期間報一個棄用通知。

當拋出致命錯誤的時候,會建立 $php_errormsg 局部變量。 PHP 7.2 中應該使用 error_get_last 和 error_clear_last 替代這種作法。

create_function() 能夠建立一個具備函數名稱的函數,將函數參數和函數體做爲該函數的列表傳入。由於安全問題和性能表現不佳,它被標記爲棄用,鼓勵用封裝替代。

mbstring.func_overload ini 設置爲非零值已經被標記爲棄用。

(unset) cast 是個老是返回 null 的表達式,而且毫無用處。

若是傳入第二個參數,parse_str() 將查詢字符串解析到數組當中, 不然解析到本地符號表。 由於安全緣由, 不建議 在函數做用域中動態設置變量,使用不帶第二個參數的 parse_str() 將拋一個棄用通知。

gmp_random() 是平臺相關的,將會被廢棄。使用 gmp_random_bits() 和 gmp_random_rage() 代替。

each() 在數組上迭代的行爲很是像 foreach(),但 foreach() 基於一些緣由而成爲更優選擇,例如它的速度快上 10 倍。如今在循環中使用前者將會拋出一個廢棄提示。

 assert() 函數檢查給定的斷言,並在結果爲 FALSE 的時候進行相關處理。 帶有字符串參數的 assert() 如今已經棄用,由於它有 RCE 漏洞。 zend.assertion ini 選項能夠關閉斷言表達式。

$errcontext 是一個包含產生錯誤時的局部變量數組。它可被做爲錯誤處理程序 set_error_handler() 函數的最後一個參數。

PHP 7.2 對 WordPress 用戶意味着什麼?

根據官方 WordPress 統計頁 所示,截至撰寫本文時,只有 19.8% 的 WordPress 用戶升級到了 PHP 7。只有 5%使用 PHP 7.1。你能夠看到超過 40% 的用戶仍然使用 PHP 5.6,更可怕的是超過 39% 的用戶在使用已經不受支持的 PHP 版本。截至 2016 年 12 月,WordPress.org 爲 PHP 5.6 版本的用戶修改 官方建議 爲建議使用 PHP 7 或以上的版本。
WordPress PHP 7.1 stats

WordPress PHP 7.1 數據統計

以上的數據表現並不使人愉悅,由於看上去 PHP 7 好像更快點。下面是一些統計數據:

  • PHP 官方 基準測試 顯示 PHP 7 容許系統每秒執行2次請求,與 PHP 5.6 相比,幾乎只是通常的延遲。
  • Christian Vigh 也發佈了一個 PHP 性能測試對比 他發現 PHP 5.2 比 PHP 7 慢了近 400%。

咱們在 2018 運行了性能基準測試 PHP 5.6 vs PHP 7 vs HHVM。與上述基準測試相似,咱們發現 PHP 7.2 與 PHP 5.6 相比每秒可執行幾乎三倍數量的事務(請求)。

WordPress benchmarks

WordPress 基準測試

  • WordPress 4.9.4 PHP 5.6 基準測試結果: 49.18 req/sec
  • WordPress 4.9.4 PHP 7.0 基準測試結果: 133.55 req/sec
  • WordPress 4.9.4 PHP 7.1 基準測試結果:134.24 req/sec
  • WordPress 4.9.4 PHP 7.2 基準測試結果:148.80 req/sec ?
  • WordPress 4.9.4 HHVM 基準測試結果:144.76 req/sec

許多東西在僅僅在更新上比較慢,由於要花時間去參與測試全部新的第三方插件和主題確保它們能夠正常運行。不少時候,慢是由於它們還沒完成。不肯定你運行的 PHP 是什麼版本?其中一個很最簡單的方法就是使用這個工具  Pingdom  或者 Google Chrome開發工具.。第一個 HTTP 請求頭通常將會展現你的版本。

Check version of PHP

檢查 PHP 版本

這將依賴於主機不修改 X-Powered-By 頭信息的值。若是修改了的話,你可能就看不到 PHP 的版本信息了,這種狀況下你須要 經過 FTP 上傳文件.。或者你老是去詢問主機。

升級到 PHP 7.2

PHP 7.2 還有一部分沒完成,可是你能夠先嚐嚐鮮。你能夠 測試你的 WordPress 本地站點 或者在相似 Docker 環境中檢查你的腳本,你能夠在命令行中測試比較不一樣的 PHP 版本。

結語

準備好切換到 PHP 7.2 了嗎?不過至少但願你首先已通過渡到了 PHP 7 以上的版本了。若是你如今還沒準備好測試的話,那麼,升級你的腳本,檢查你的代碼,說說你對 PHP 7.2 的首次體驗。

更多現代化 PHP 知識,請前往 Laravel / PHP 知識社區
相關文章
相關標籤/搜索