PHP7.3發布啦


 

作為PHP5的最后一個版本,也是目前使用最廣泛的PHP版本,PHP 5.6始於公元2014年(不是1804年,嘿嘿),其第一個測試版PHP 5.6 alpha 1版於2014年1月發布。隨機產生了第一個由國人(鳥哥,惠新宸)參與主研的性能大規模提升版本PHPNG(PHP next generation,下一代PHP),2015年基於PHPNG接着就產生PHP 7版本。PHP7帶來了革命性的性能提高,其運行速率是5.6的兩倍還高以及其他改善,比如64位支持、類型申明、運行時優化等。從2015年開始官方就一直推薦大家盡快升級到php7,雖然當時擴展支持還是很成問題。

根據最新的W3techs統計,目前PHP 7大概占了超過16.6%的PHP份額。 總體上PHP仍然擁有大約83%的網站服務器端開發語言的絕大多數比例。

 

根據PHP開發支持周期,到今年12月31日后,PHP 5.6不在有官方支持。所以現在只剩下半年時間你升級你的PHP到PHP7。此后PHP5的命運就會終結,而且就蟲蟲所致目前基本上絕大多數的框架和程序都已經完美的支持PHP7了。

 

 

性能測試:PHP 7.3比PHP 7.0快25%

有很多性能測試對比都揭示了PHP 7比PHP 5.6快至少2倍。下面是各大php框架心性能對比圖:

 

下面最新Phoronix基准測試結果則顯示了自PHP7發布以來PHP 7的性能對比情況。最新版本的PHP 7.3 Alpha比以初始版本的PHP 7在系能上的改善的也是相當客觀的。根據最新數據PHP 7.3是比PHP 5.6快3倍!比PHP 7.0快25%。不說別的光這性能對比圖就能給烈日炎炎的夏日帶來絲絲涼意。而且這還可以直接體現在費用上,比如升級PHP7后,Badoo大概每年可減少100w美刀。

 

Badoo公司的數據:

 

PHP 7兼容行檢查

截止目前基本上絕大多數的PHP都可以完美的支持PHP7.0了。但是可能你恰好有一些歷史遺留的腳本和程序,那么也好辦,社區已經有好多的工具做兼容性檢查,甚至給出直接的代碼轉譯,以下是幾個值得推薦的工具:

php7cc:一個很不錯的工具,不過目前已經不再更新了。(github地址: /sstalle/php7cc)

 

php7mar:PHP 7遷移助手,蟲蟲強烈推薦的工具。 (github地址:/Alexia/php7mar)

 

使用方法:

php mar.php -f="/path/to/project/root/" -r="/path/to/output/"

phan:PHP腳本的靜態分析器。 可以做當做php 7的語法檢查器。(github地址:/phan/phan)

 

使用方法:phan --project-root-directory --progress-bar -o phan.out

phpstan - PHP靜態分析和兼容性檢查工具。(github地址:/phpstan/phpstan)

 

PHP 7性能設置要點

1. Opcache

首先,確保已經啟用了OpCache。可以通過主配置文件php.ini或它獨特的配置文件opcache.ini文件(例如/etc/php/7.2/fpm/conf.d/10-opcache.ini)。來進行設置。

zend_extension=opcache.so

opcache.enable=1

opcache.enable_cli=1

可以使用phpinfo()檢查,也可以通過終端命令

php -v or php -i | grep opcache.enable

確認PHP OpCache已啟用后,很多的ln(a)mp套件都有一個opCache監控腳本,可以對其系能進行實時監控,如下圖

 

2、設置合適的realpath_cache_size

通過設置合宜的realpath_cache_size值可以改善你服務器的並發:

realpath_cache_size = 256k

realpath_cache_ttl = 300

 

3、禁止mysqlnd.collect_statistics

mysqlnd.collect_statistics = Off

mysqlnd.collect_memory_statistics = Off

線上服務器選擇禁止這兩個選項,可以減少不必要的數據庫訪問。如果需要相關統計,可以使用MySQL工具或者監控。

4、使用新的編譯器

GCC 4.8編譯器下編譯時PHP才能開啟Global Register for opline and execute_data支持, 這個會帶來5%左右的性能提升。

5、開啟Transparent HugePage (透傳大頁)

內存默認是以4KB分頁的,而虛擬地址和內存地址需要轉換,轉化時候需要進行搜索,為了加速轉換過程,可以通過內存TLB(Translation Lookaside Buffer)來。所以通過啟用大內存頁可以增加TLB 緩存命中,從而提高性能。

設置系統支持:

sysctl vm.nr_hugepages=512

php.ini 增加支持

opcache.huge_code_pages=1

關於這個值,很多實踐后發現啟用透傳大頁面后會帶來系統負載過高,cpu占用過高問題,這時候通過關閉就可以解決。所以這個參數需要實際情況斟酌測試使用。

6、開啟PGO

PHP是專門為一個項目服務,比如一個 Wordpress或者drupal站點,就可以使用PGO提高性能。

 

 

PHP 7.3正在敲響我們的大門,它帶來了新的實用功能,並棄用大量的錯誤和修復舊有BUG,目前的Beta 2版本於8月16日發布。

您可以下載當前的PHP 7.3版本以進行開發和測試,但請記住,目前這不應該在生產環境中使用。

在這篇文章中,我們將概述我認為最相關的功能和變化。但是,您可以隨時查看PHP 7.3升級說明和PHP 7.3請求注釋中的功能,更改和錯誤修復的完整列表。

PHP更新時間表

靈活的Heredoc和Nowdoc語法

這可能是PHP 7.3中最相關的改進之一,我認為值得更多關注。因此,在深入研究PHP 7.3 heredoc / nowdoc之前,我們將快速概述這個有用的核心功能。

1.heredoc和nowdoc語法概述

heredoc語法提供了一種添加大量文本的方法,而無需像雙引號那樣轉義。一個heredoc開始<<<后跟一個標記,並以相同的標記結束,然后是分號。這是一個例子:

print <<<EOT Heredoc text behaves just like a double-quoted string, without the double quotes. EOT;
 

nowdoc的行為很像heredoc,但有一些例外:

標識符用單引號括起來(<<<‘EOT’)

在nowdoc內部沒有解析

這是nowdoc的一個例子:

print <<<'EOT' Nowdocs are to single-quoted strings what heredocs are to double-quoted strings. EOT;
 

Heredocs和nowdocs共享相同的規則來規范結束標記的使用:

結束標記必須從該行的第一列開始

標記必須遵循與PHP中任何其他標簽相同的命名規則:它必須僅包含字母數字字符和下划線,並且必須以非數字字符或下划線開頭。

PHP手冊警告:

請注意,除了分號(;)之外,具有結束標識符的行必須不包含其他字符,這一點非常重要。這尤其意味着標識符可能不會縮進,並且在分號之前或之后可能沒有任何空格或制表符。同樣重要的是要意識到結束標識符之前的第一個字符必須是本地操作系統定義的換行符。這是\n在UNIX系統上,包括macOS。結束分隔符也必須后跟換行符。

PHP 7.2語法無效:

class foo { public $bar = <<<EOT bar EOT; } // Identifier must not be indented
 

PHP 7.2有效語法:

class foo { public $bar = <<<EOT bar EOT; }
 

為了簡短起見,在PHP 7.2中:

結束標記可能不會縮進

帶有結束標記的行可能不包含空格或制表符等字符

結束標記之前的第一個字符必須是換行符

結束標記必須后跟換行符

很明顯,heredoc和nowdoc語法是相當嚴格的,但PHP 7.3可能會通過以下改進稍微改變一下。

1.允許縮進關閉標記並剝離前導空格

使用PHP 7.3,我們可以縮進結束標記,我們可以安全地編寫以下代碼:

class foo { public $bar = <<<EOT bar EOT; }
 

結束標記的縮進設置將從主體的每一行剝離的空白(或制表符)的數量。但要小心:關閉標記不應該比身體的任何其他線進一步縮進。

請參閱以下代碼:

class foo { public $bar = <<<EOT bar EOT; }
 

上面的代碼會發出以下解析錯誤:

解析錯誤:行%d上的%s中的體縮進級別(期望至少縮進…)無效

剝離制表符和空格允許我們將heredoc / nowdoc的主體縮進到周圍代碼的相同級別,並且在主體的每一行之前沒有不必要的空格。

我們可以使用制表符和空格來縮進,但我們不允許混合使用它們。這意味着我們必須對結束標記和正文的任何​​行使用相同的縮進字符。如果有不同的縮進字符,我們會期望一種不同類型的解析錯誤(無效縮進)。

2.從結算標記中刪除尾隨新行要求

目前,新行必須遵循標記才能終止heredoc / nowdoc。PHP 7.3會改變這一點,並允許我們在同一行終止heredoc / nowdoc。這是RFC的一個例子:

PHP 7.2有效語法:

$values = [<<<END a b c END , 'd e f'];
 

PHP 7.3有效語法:

$values = [<<<END a b c END, 'd e f'];
 

無論如何,在選擇標記的名稱時要小心,因為“偶爾”如果它與你在heredoc / nowdoc主體中使用的單詞相匹配,你可能會遇到錯誤。

在函數調用中允許使用尾隨逗號

尾隨逗號(或“最終逗號”)是附加到元素,參數或屬性列表的逗號,它們在頻繁附加新值的上下文中派上用場,因為它們可以防止由於缺少逗號而導致的錯誤。在PHP中,允許在數組中使用尾隨逗號,從PHP 7.2開始,它們在分組命名空間中是允許的。

從PHP 7.3開始,函數聲明中將允許使用尾隨逗號。變量函數提供了一個上下文示例,其中尾隨逗號非常有用:

foo( $bar, $baz, );
 

我們在創建數組時可以使用尾隨逗號compact(),以便返回格式化字符串sprintf(),或者合並數組時:

$newArray = array_merge( $arrayOne, $arrayTwo, ['foo', 'bar'], );
 

此外,尾隨逗號對調試很有用:

var_dump( $foo, $bar, $baz, ); 強大
 

unset()和isset():

unset( $foo, $bar, $baz, ); isset( $foo, $bar, $baz, );
 

方法調用和附件中也允許使用尾隨逗號。

注意:此更改僅影響函數調用。函數聲明語法不會改變。此外,不允許使用獨立逗號,多個尾隨逗號和引號。

JSON_THROW_ON_ERROR

PHP 7.3帶來的最受歡迎的功能之一提供了一種處理JSON錯誤的新方法。這不是核心功能,而是JSON擴展的一個補充,它將改變json_decode()和json_encode()的錯誤行為。

目前,json_decode()返回null錯誤,但null也可以是有效的結果。這可能令人困惑,因為

只能通過調用json_last_error()或者知道是否發生錯誤json_last_error_msg(),它分別以機器可讀和人類可讀的形式返回全局錯誤狀態。- PHP RFC

json_encode()返回FALSE錯誤。這更清楚,因為存在特定的錯誤值。無論如何,這兩個函數既不會在出錯時停止程序執行,也不會拋出任何警告。

PHP 7.3的提議:

該RFC而是提出了添加新的選項標志值json_decode()和json_encode(),JSON_THROW_ON_ERROR。傳遞此標志時,會更改這些函數的錯誤行為。全局錯誤狀態保持不變,如果發生錯誤,否則將設置它,這些函數將拋出一個JsonException消息和代碼設置為任何json_last_error()和json_last_error_msg()否則將分別。

下面是一個顯示拋出JSON錯誤的簡單方法的示例:

try { json_decode("{", false, 512, JSON_THROW_ON_ERROR); } catch (\JsonException $exception) { echo $exception->getMessage(); // echoes "Syntax error" }
 

在出錯時拋出異常將帶來您在RFC上列出的幾個優點。

注意:傳遞的無效深度參數json_decode()輸出警告並返回NULL。此行為不會受到影響JSON_THROW_ON_ERROR。同樣,參數解析錯誤不會受到影響JSON_THROW_ON_ERROR並繼續產生警告。

list()參考分配

參考分配意味着什么?

請考慮以下行:

$b = &$a;
 

這里$b獲取值$a,但該值不會從中復制$a到$b。在PHP中,我們可以通過引用分配值,這意味着兩個變量可以指向相同的數據,並且對任何變量的每個更改都會影響原始數據。以下是PHP手冊中的一個示例:

<?php $a = 3; $b = &$a; // $b is a reference to $a print "$a\n"; // prints 3 print "$b\n"; // prints 3
 

現在,讓我們改變以下的值$a:

$a = 4; // change $a print "$a\n"; // prints 4 print "$b\n"; // prints 4 as well, since $b is a reference to $a, which has been changed
 

什么是list()構造以及如何使用PHP 7.3進行更改

列表()語言結構可以用來“就像它們是在一個數組指派變量”,但與list()我們目前不允許通過參考分配變量值。

PHP 7.3應該改變這一點,允許我們通過引用也使用list()構造來分配變量,如以下示例所示:

$array = [1, 2]; list($a, &$b) = $array;
 

這與:

$array = [1, 2]; $a = $array[0]; $b =& $array[1];
 

is_countable函數

PHP 7.3附帶的另一個功能是is_countable()功能。我們在嘗試count()不可數的東西時會收到錯誤。出於這個原因,為了避免警告,我們被迫添加以下代碼:

if (is_array($foo) || $foo instanceof Countable) { // $foo is countable }
 

這個RFC提出了函數is_countable(),true如果給定變量是一個數組,它返回,false否則它是一個可數變量。因此,上面的代碼可以更改如下:

if (is_countable($foo)) { // $foo is countable }
 

array_key_first(),array_key_last()

目前,我們可以使用reset(),end()和key()函數檢索數組的第一個和最后一個鍵。不幸的是,使用這些函數,無法在不更改其內部狀態的情況下收集數組的第一個或最后一個索引。其他選項通常會降低代碼的可讀性和性能。
此提議將通過向PHP核心添加兩個新函數來更改此方案:

array_key_first()

array_key_last()

在PHP 7.3中,array_key_first()並array_key_last()允許取回第一和給定數組的最后一個關鍵,而不會影響內部數組指針。這些新功能允許我們編寫不太

注意:最初的RFC提出了另外兩個函數,array_value_first()並且array_value_last()這些函數在不同的投票中投票,但尚未獲得批准,也不會成為PHP核心的參與者。

Argon2密碼哈希增強功能

Argon2是在PHP 7.2中實現的散列算法,作為Bcrypt算法的替代算法。PHP 7.2引入了PASSWORD_ARGON2I常量,可用於password_*函數:

password_hash('password', PASSWORD_ARGON2I);
 

自第一次實現以來,添加了一個新的Argon2變體,因此,在撰寫本文時,Argon2有三種變體:

Argon2d最大限度地抵御GPU破解攻擊。它更快,並使用依賴於數據的內存訪問。

Argon2i使用與數據無關的內存訪問,這是密碼散列的首選。它更慢,因為它通過內存更多的通過,以防止權衡攻擊。

Argon2id是一個混合版本,它結合了第一次通過內存的Argon2i方法和后續通過的Argon2d方法。

建議在Internet上使用Argon2id,除非有充分理由特別喜歡其他變體。

新RFC建議在password_ *函數中使用新PASSWORD_ARGON2ID常量實現Argon2id :

password_hash('password', PASSWORD_ARGON2ID);
 

實現與Argon2i實現相同,並且將接受相同的成本因素:

甲存儲器成本它定義了應散列期間被消耗KIB的數(默認值是1 << 10,或1024 KIB,或1 MIB)

甲時間成本定義散列算法的迭代次數(默認為2)

甲並行因子,它設置散列(默認為2)時,將用於並行線程的數目

請參閱以下代碼:

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

棄用

以下函數/功能將在PHP 7.3中棄用,並且不會晚於PHP 8.0刪除。

棄用並刪除image2wbmp()

所述image2wbmp()函數輸出或保存WBMP給定圖像的版本。此函數有三個參數:圖像資源,文件名(保存文件的路徑)和前景色。
從PHP 5.0開始,它與imagewbmp()完全相同,因此該RFC建議棄用並刪除它。
從PHP 7.3開始,每次調用image2wbmp()都會發出棄用警告。刪除后,每次調用都會引發致命錯誤。

棄用和刪除不區分大小寫的常量

PHP目前支持區分大小寫和不區分大小寫的常量。無論如何,支持不區分大小寫的常量,但被認為是功能上的不一致,並且使用起來很復雜。
該提案從以下前提開始:

類常量始終區分大小寫

聲明的全局常量const始終區分大小寫

define()默認情況下,定義的常量區分大小寫

此外,PHP語言參考明確指出:

默認情況下,常量區分大小寫。按照慣例,常量標識符總是大寫的。

話雖這么說,這個RFC提出了以下變化:

使用define()第三個參數設置為true- PHP 7.3 棄用調用

使用與聲明不同的大小寫(不包括true,false和null)來棄用不區分大小寫的常量- PHP 7.3

刪除聲明不區分大小寫的常量的可能性 – PHP 8.0

轉換true,false並null從特例,常數為保留關鍵字- PHP 8.0

PHP 7.3的附加棄用

以下是PHP 7.3中不推薦使用的功能的快速列表。它並非詳盡無遺,它們只是我個人認為更具相關性的棄用提案。有關建議的棄用的完整列表,請參閱PHP 7.3的棄用。

未記錄的mbstring函數別名:有許多未記錄的mbstring函數別名,它們是使用mb_前綴的等效函數的重復。例如,mbereg是別名mb_ereg。
所有這些函數都將被標記為已棄用,並且在編譯期間遇到它們時將拋出棄用通知。

帶整數針的字符串搜索功能:這些功能通常在字符串針上運行。如果給出非字符串指針,則將其轉換為整數並作為字符的序數值應用(請參閱PHP手冊中的更多內容)。這是RFC的一個例子:

$str = "There are 10 apples"; var_dump(strpos($str, "10")); // int(10) var_dump(strpos($str, 10)); // bool(false)
 

這被認為是混亂並導致不可預測的問題,因為類型可能隨用戶數據源而改變。因此,如果將非字符串針傳遞給以下函數之一,則RFC建議發出棄用警告:

strpos

strrpos

stripos

strripos

strstr

strchr

strrchr

stristr

在PHP 8.0中,應刪除棄用警告,並且針應自動轉換為字符串。

正在尋找改進WordPress開發工作流程的方法?

Kinsta的托管解決方案是由開發人員為開發人員構建的。Git,PHP 7,SSH和WP-CLI,以及強大的登台和克隆環境為您提供了更快地構建網站所需的工具!

查看我們的高級功能

fgetss()功能和string.strip_tags流過濾器:fgetss()與string.strip_tags從流條標簽,因為它們讀取它。函數和過濾器都暴露了strip_tags()功能,使得實現strip_tags()更加復雜,因為需要流式狀態機。此外,RFC指出了這些功能的另一個缺點:

另一方面,這些功能似乎沒什么用處。strip_tags()由於其局限性和已知錯誤,本身已經很少有合法的應用程序。除此之外,無需為流應用程序提供本機支持。

因此RFC建議標記fgetss(),gzgetss()並SplFileObject::fgetss()棄用。

概要

在撰寫本文時,PHP 7.3處於Beta 2階段,根據准備任務時間表,它將於12月中旬正式發布。它將帶給我們如靈活的heredocs和nowdocs,函數調用中的尾隨逗號,list()參考分配等等。


免責聲明!

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



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