PHP 7.4中的新功能(即將推出)

PHP 7.4是下一個PHP 7次要版本,預計將於2019年11月21日發布到General Availability。因此,現在是時候深入了解一些最令人興奮的新增功能和新功能,這將使PHP更快,更可靠。

實際上,即使PHP 7.4能夠顯著提高性能並提高代碼可讀性,PHP 8也將成為PHP性能的真正里程碑,因為JIT包含的提議已經獲得批准。

無論如何,今天我們正在經歷PHP 7.4中我們期望的一些最有趣的功能和更改。因此,在您閱讀本文之前,請務必保存以下日期:

你厭倦了緩慢的WordPress主機和可怕的支持嗎?我們在Kinsta做不同的事情。查看我們的託管計劃

  • 6月6日:PHP 7.4 Alpha 1
  • 7月18日:PHP 7.4 Beta 1 – 功能凍結
  • 11月21日:PHP 7.4 GA發布

您可以在官方RFC頁面上查看功能和添加的完整列表。

PHP 7.4發布日期:

PHP 7.4計劃於2019年11月21日發布。它是下一個PHP 7次要版本,應該可以顯著提高性能並提高代碼可讀性。

使用PHP 7.4支持PHP的新功能?

在這篇文章中,我們將介紹應該添加到PHP 7.4最終版本的語言中的一些更改和功能:

  • 支持在數組內部解壓縮 – 數組傳播運算符(核心)
  • 箭頭函數具有隱式按值範圍綁定(Core)
  • Nulled Coalesce assign(?? =)運算符(Core)
  • 類型屬性(核心)
  • 弱參考(核心)
  • 協變返回類型和逆變參數(核心)
  • 預載入(OPcache)
  • 新的自定義對象序列化機制(SPL)
  • 棄用

PHP 7.4是即將推出的PHP 7次要版本,它將使PHP更快,更可靠。 ?查看我們對新功能的深入了解!點擊鳴叫

忘記array_merge:PHP 7.4在數組表達式中引入Spread運算符

自PHP 5.6起可用,參數解包是將數組和Traversable解包為參數列表的語法。要解壓縮數組或Traversable,必須以…(3點)為前綴,如下例所示:

function test(… $ args){var_dump($ args); } test(1,2,3);

現在這個PHP 7.4 RFC建議將此功能擴展到數組定義:

$ arr =(… $ args);

擴展運算符在數組表達式中的第一個聲明好處就是性能。實際上,RFC文檔指出:

Spread運算符應該比array_merge具有更好的性能。這不僅是因為spread運算符是一種語言結構,而array_merge是一個函數,而且因為編譯時優化可以用於常量數組。

Spread運算符的一個顯著優點是它支持任何可遍歷的對象,而array_merge函數僅支持數組。

以下是數組表達式中參數解包的示例:

$ parts =('apple','pear'); $ fruits =('banana','orange',… $ parts,'watermelon');後續代碼var_dump($水果);

如果在PHP 7.3或更早版本中運行此代碼,PHP會拋出一個Parse錯誤:

解析錯誤:語法錯誤,意外'…'(T_ELLIPSIS),在第3行的/app/spread-operator.php中期待')'

相反,PHP 7.4將返回一個數組:

array(5){(0)=> string(6)「banana」(1)=> string(6)「orange」(2)=> string(5)「apple」(3)=> string(4) 「pear」(4)=> string(10)「watermelon」}

RFC聲明我們可以多次擴展同一個數組。此外,我們可以在數組中的任何位置使用Spread Operator語法,因為可以在spread運算符之前或之後添加常規元素。因此,以下代碼將按預期工作:

$ arr1 =(1,2,3); $ arr2 =(4,5,6); $ arr3 =(… $ arr1,… $ arr2); $ arr4 =(… $ arr1,… $ arr3,7,8,9);

也可以將函數返回的數組直接解包到新數組中:

function buildArray(){return('red','green','blue'); } $ arr1 =(… buildArray(),'pink','violet','yellow');

PHP 7.4輸出以下數組:

array(6){(0)=> string(3)「red」(1)=> string(5)「green」(2)=> string(4)「blue」(3)=> string(4) 「pink」(4)=> string(6)「violet」(5)=> string(6)「yellow」}

我們也可以使用生成器語法:

function generator(){for($ i = 3; $ i <= 5; $ i ++){yield $ i; $ arr1 =(0,1,2,… generator());

但我們不允許解壓縮通過引用傳遞的數組。請考慮以下示例:

$ arr1 =('red','green','blue'); $ arr2 =(…&$ arr1);

如果我們嘗試通過引用解壓縮數組,PHP會拋出以下Parse錯誤:

解析錯誤:語法錯誤,第3行的/app/spread-operator.php中出現意外的'&'

無論如何,如果第一個數組的元素是通過引用存儲的,那麼它們也通過引用存儲在第二個數組中。這是一個例子:

$ arr0 ='red'; $ arr1 =(&$ arr0,'green','blue'); $ arr2 =('white',… $ arr1,'black');

這是我們用PHP 7.4獲得的:

array(5){(0)=> string(5)「white」(1)=>&string(3)「red」(2)=> string(5)「green」(3)=> string(4) 「blue」(4)=> string(5)「black」}

Spread運營商提案以43比1的票數通過。

箭頭功能2.0(短暫閉包)

在PHP中,匿名函數被認為是非常冗長且難以實現和維護。這個RFC建議引入更簡單,更清晰的箭頭函數(或簡短閉包)語法,這樣我們就可以大大清理PHP代碼了。

請考慮以下示例:

function cube($ n){return($ n * $ n * $ n); } $ a =(1,2,3,4,5); $ b = array_map('cube',$ a);的print_r($ b)的

PHP 7.4允許使用更簡潔的語法,上面的函數可以重寫如下:

$ a =(1,2,3,4,5); $ b = array_map(fn($ n)=> $ n * $ n * $ n,$ a);的print_r($ b)的

目前,由於使用了語言結構,匿名函數(閉包)可以繼承父作用域中定義的變數,如下所示:

$ factor = 10; $ calc = function($ num)use($ factor){return $ num * $ factor; };

但是在PHP 7.4中,父作用域中定義的變數由值隱式捕獲(隱式按值作用域綁定)。所以我們可以將上面看到的整個函數寫在一行上:

$ factor = 10; $ calc = fn($ num)=> $ num * $ factor;

父作用域中定義的變數可以在箭頭函數中使用,就像我們使用use($ var)一樣,並且不可能從父作用域修改變數。

新語法是對語言的一個很大改進,因為它允許我們構建更易讀和可維護的代碼。我們還可以使用參數和返回類型,默認值,可變長度參數列表(可變函數),我們可以通過引用傳遞和返回等。最後,短閉包也可以在類方法中使用,並且它們可以使用$ this變數就像常規閉包一樣。

此RFC已獲得51至8票的批准,因此我們可以預期它將成為PHP 7.4新增內容的一部分。

空融合分配運算符

添加PHP 7時,當我們需要將三元運算符與isset()結合使用時,coalesce運算符(??)會派上用場。它返回第一個操作數(如果存在且不為NULL)。否則,它返回第二個操作數。這是一個例子:

$ username = $ _GET('user')?? '沒有人';

這段代碼的作用非常簡單:它獲取請求參數並設置默認值(如果它不存在)。該行的含義是清楚的,但是如果我們在RFC的這個例子中有更長的變數名稱呢?

$ this-> request-> data('comments')('user_id')= $ this-> request-> data('comments')('user_id')?? '值';

從長遠來看,這段代碼可能有點難以維護。因此,旨在幫助開發人員編寫更直觀的代碼,此RFC建議引入空合併賦值運算符(?? =)。因此,我們可以編寫以下代碼,而不是編寫前面的代碼:

$ this-> request-> data('comments')('user_id')?? ='value';

如果left-hand參數的值為null,則使用右側參數的值。
注意,雖然coalesce運算符是比較運算符,但?? =是賦值運算符。

該提案已獲得37票對4票的批准。

鍵入的屬性2.0

參數類型聲明或類型提示允許指定預期傳遞給函數或類方法的變數的類型。類型提示是自PHP 5以來可用的功能,從PHP 7.2開始,我們可以將它們與對象數據類型一起使用。現在,PHP 7.4通過添加對第一類屬性類型聲明的支持,使類型提示向前邁出了一步。這是一個非常基本的例子:

class User {public int $ id; public string $ name; }

void和callable除外,支持所有類型:

public int $ scalarType; protected ClassName $ classType; private?ClassName $ nullableClassType;

RFC解釋了不支持void和callable的原因:

不支持void類型,因為它沒用,並且語義不清楚。

不支持可調用類型,因為其行為取決於上下文。

所以我們可以安全地使用bool,int,float,string,array,object,iterable,self,parent,任何類或介面名稱,以及可空類型(?type)。

類型可用於靜態屬性:

public static iterable $ staticProp;

它們也允許使用var表示法:

var bool $ flag;

可以設置默認屬性值,當然必須與聲明的屬性類型匹配,但只有可空屬性可以具有默認的空值:

public string $ str =「foo」; public?string $ nullableStr = null;

相同的類型適用於單個聲明中的所有屬性:

public float $ x,$ y;

如果我們在屬性類型上出錯,會發生什麼?請考慮以下代碼:

class User {public int $ id; public string $ name; } $ user = new User; $ user-> id = 10; $ user-> name =();

在上面的代碼中,我們聲明了一個字元串屬性類型,但我們將數組設置為屬性值。在這種情況下,我們得到以下致命錯誤:

致命錯誤:未捕獲TypeError:類型屬性User :: $ name必須是字元串,數組在/app/types.php中使用:9

此RFC已獲得70至1票的批准。

弱參考

通過此RFC,PHP 7.4引入了WeakReference類,它允許程序員保留對對象的引用,該對象不會阻止對象本身被破壞。

目前,PHP通過使用像pecl-weakref這樣的擴展來支持弱引用。無論如何,新API與記錄的WeakRef類不同。

以下是該提案的作者Nikita Popov的一個例子:

$ object = new stdClass; $ weakRef = WeakReference :: create($ object);後續代碼var_dump($ weakRef->的get());未設置($對象);後續代碼var_dump($ weakRef->的get());

第一個var_dump列印對象(stdClass)#1(0){},而第二個var_dump列印NULL,因為被引用的對象已被銷毀。

此RFC以28票對5票通過。

協變返回和逆變參數

方差是類層次結構的一個屬性,描述了類型構造函數的類型如何影響子類型。通常,類型構造函數可以是:

  • 不變數:如果超類型的類型約束子類型的類型。
  • 協變:如果保留類型的排序(類型從更具體到更通用的順序排序)。
  • 逆變:如果它顛倒了順序(類型從更通用到更具體的順序排序)。

目前,PHP幾乎沒有參數和返回類型,只有少數例外。該RFC建議允許參數類型和返回類型的協方差和逆變,還提供了幾個代碼示例。

以下是協變返回類型的示例:

interface Factory {function make():object; class UserFactory實現Factory {function make():User; }

以下是逆變參數類型的示例:

interface Concatable {function concat(Iterator $ input); class Collection實現Concatable {//接受所有迭代,而不僅僅是Iterator函數concat(iterable $ input){/ *。 。 。 * /}}

有關PHP 7.4中協方差和逆變的詳細信息,請參閱RFC。

這個RFC以39比1的票數通過。

預載入

德米特里·斯托戈夫的這個提議是我們最喜歡的,因為它應該會帶來顯著的性能提升。預載入是在模塊初始化時將庫和框架載入到OPCache中的過程(閱讀有關PHP生命周期的更多信息)。

PHP生命周期

PHP生命周期(圖片來源:PHP Internals)

以下是德米特里的預言:

在伺服器啟動時 – 在運行任何應用程序代碼之前 – 我們可以將一組PHP文件載入到內存中 – 並使其內容「永久可用」到該伺服器將服務的所有後續請求。這些文件中定義的所有函數和類將可用於開箱即用的請求,與內部實體完全相同。

這些文件在伺服器啟動時載入,在任何應用程序之前執行,並且可用於將來的任何請求。這在性能方面很棒。

預載入由特定的php.ini指令控制:opcache.preload。該指令指定在伺服器啟動時編譯和執行的PHP腳本。此文件可用於預載入其他文件,包括它們或通過opcache_compile_file()函數(有關PHP文檔的更多信息)。

但是有一個缺點。事實上,RFC明確指出:

預載入的文件永遠保存在opcache內存中。如果沒有其他伺服器重新啟動,修改其相應的源文件將不起任何作用。

但是,預載入文件中定義的所有函數將永久載入到PHP函數和類表中,並且可用於將來的每個請求。這將帶來良好的性能改進,即使這些改進可能變化很大。

您可以在官方預載入RFC頁面上閱讀有關預載入的限制和例外的更多信息。

新的自定義對象序列化機制

這是Nikita Popov以大多數選票獲得批准的另一項提案。

您的主人是否充分利用了最新技術?在Kinsta,我們使用針對WordPress優化的最佳技術堆棧。看看我們的計劃

目前,我們有兩種不同的機制來自定義PHP中的對象:

  • __sleep()和__wakeup()魔術方法
  • Serializable介面

根據Nikita的說法,這兩個選項都存在導致代碼複雜且不可靠的問題。您可以深入了解RFC中的這個主題。在這裡我只提到新的序列化機制應該通過提供兩個新的魔術方法__serialize()和__unserialize()來結合現有的兩種機制來防止這些問題。

該提案以20票對7票獲得通過。

棄用

PHP 7.4將棄用以下函數/功能。有關更全面的棄用列表,請查看PHP 7.4升級說明。

更改連接運算符的優先順序

目前,在PHP中,「+」和「 – 」算術運算符和「。」字元串運算符是左關聯的並且具有相同的優先順序(閱讀有關運算符優先順序的更多信息)。

例如,請考慮以下行:

回聲「總和:」。 $ a + $ b;

在PHP 7.3中,此代碼生成以下警告:

警告:第4行的/app/types.php中遇到非數字值

這是因為連接是從左到右進行評估的。它與編寫以下代碼相同:

echo(「sum:」。$ a)+ $ b;

此RFC建議更改運算符的優先順序,使「。」的優先順序低於「+​​」和「 – 」運算符,以便在字元串連接之前始終執行加法和減法。該行代碼應該等同於以下內容:

回聲「總和:」。 ($ a + $ b);

這是一個兩步提案:

  • 從版本7.4開始,當遇到帶有「+」,「 – 」和「。」的未加表示的表達式時,PHP應發出棄用通知。
  • 應使用PHP 8添加這些運算符的實際優先順序更改。

這兩項提案都獲得了大多數選票的批准。

棄用左關聯三元運算符

在PHP中,三元運算符與許多其他語言不同,是左關聯的。根據Nikita Popof的說法,對於在不同語言之間切換的程序員來說,這可能會讓人感到困惑。

目前,在PHP中,以下代碼是正確的:

$ b = $ a == 1? '一':$ a == 2? '兩個':$ a == 3? '三':'其他';

它被解釋為:

$ b =(($ a == 1?'one':$ a == 2)?'two':$ a == 3)? '三':'其他';

這可能會導致錯誤,因為它可能不是我們打算做的。因此,本RFC建議棄用並刪除三元運算符的左關聯性使用,並強制開發人員使用括弧。

這是另一個兩步建議:

  • 從PHP 7.4開始,沒有明確使用括弧的嵌套三元組將拋出棄用警告。
  • 從PHP 8.0開始,將出現編譯運行時錯誤。

該提案已獲得35票對10票的批准。

PHP 7.4對WordPress用戶意味著什麼?

PHP是Web上使用最廣泛的伺服器端編程語言。據W3Techs稱,截至2019年5月28日,PHP的使用量仍在增長:

在我們所知道的伺服器端編程語言的所有網站中,有79.0%使用PHP。

PHP版本

PHP使用情況(2019年5月)

不幸的是,使用已知伺服器端編程語言的52.4%的網站仍然使用PHP 5。如果您添加仍使用PHP 7.0的用戶數,則可以發現絕大多數網站都運行不受支持的PHP版本。

支持的PHP版本

支持的PHP版本(圖像源:支持的版本)

根據官方的WordPress統計頁面,截至撰寫本文時,高達67%的所有WordPress網站都運行不受支持的PHP版本。只有3%多一點使用最新版本:PHP 7.3。您可以看到,超過31%的大多數用戶仍在PHP 5.2上運行。

WordPress PHP版本

WordPress PHP版本(2019年5月)

我們強烈建議您向主機索取支持的PHP版本,最好根據WordPress的官方要求。截至撰寫本文時,2019年5月,WordPress要求:

  • PHP 7.3或更高版本。
  • MySQL 5.6或更高版本或MariaDB版本10.1或更高版本。
  • HTTPS支持

PHP 7性能

從性能的角度來看,上面的數字尤其令人沮喪,因為PHP 7已經顯示出明顯更快。以下是一些統計數據:

  • 官方PHP基準測試表明,與PHP 5.6相比,PHP 7允許系統每秒執行兩倍的請求,幾乎是延遲的一半。
  • Christian Vigh還發布了一個PHP性能比較,他發現PHP 5.2比PHP 7慢400%。
  • Phoronix使用PHP 7.4 Alpha進行了一些早期基準測試,發現它比PHP 7.3略快。

我們使用PHP 7.3運行自己的PHP性能基準測試。我們看到,與PHP 5.6相比,PHP 7.3上的WordPress 5.0每秒執行的事務(請求)數量幾乎是其三倍。我們即將發布PHP 7.4基準測試!

WordPress 5.0 PHP基準測試

WordPress 5.0 PHP基準測試

  • WordPress 5.0 PHP 5.6基準:91.64 req / sec
  • WordPress 5.0 PHP 7.0基準測試結果:206.71 req / sec
  • WordPress 5.0 PHP 7.1基準測試結果:210.98 req / sec
  • WordPress 5.0 PHP 7.2基準測試結果:229.18 req / sec
  • WordPress 5.0 PHP 7.3基準測試結果:253.20 req /sec?

由於測試新的所有第三方插件和主題以確保它們正常運行所涉及的時間很多,因此很多都很難更新。但很多時候,歸結為他們還沒有完成它。

檢查您的PHP版本

不確定你正在運行什麼版本的PHP?最簡單的檢查方法之一是使用Pingdom或Google Chrome Devtools等工具。第一個HTTP請求標頭通常會顯示版本。

檢查Pingdom中的PHP版本

檢查Pingdom中的PHP版本

這取決於主機不修改X-Powered-By標頭值。但是,許多人出於安全原因(包括Kinsta)。如果是這樣,您可能看不到您的PHP版本。在這種情況下,如果您運行的是WordPress 5.2或更高版本,則可以使用新的站點運行狀況工具。轉到「工具」→「站點健康」→「信息」,在「伺服器」部分下,您將找到伺服器的PHP版本。

使用WordPress站點運行狀況工具檢查PHP版本

使用WordPress站點運行狀況工具檢查PHP版本

或者,您可以安裝免費插件,如版本信息,它將在您的WordPress管理儀錶板的頁腳中顯示一些基本的伺服器信息。查看PHP版本的其他幾種方法包括通過FTP上傳文件,或者只是聯繫主機並詢問。

更新到PHP 7.4

PHP 7.4的最終版本還沒有。但是,您可以在本地測試WordPress站點或在Docker等環境中檢查腳本,這樣您就可以從命令行測試不同版本的PHP。

一旦發布了PHP 7.4,您就可以利用Kinsta的臨時環境,因為這將更像現場製作網站。在MyKinsta儀錶板中通過幾次簡單的點擊創建一個臨時環境。

WordPress登台環境

WordPress登台環境

只需在「工具」下更改暫存站點的PHP引擎,即可開始測試以確保第三方插件和主題的兼容性。

改為PHP 7.3

改為PHP 7.3

我們將在正式發布一般可用性並由我們的開發人員進行全面測試後立即添加對PHP 7.4的支持。同時,您可能希望使用Docker等工具在計算機上運行PHP 7.4自己的測試。

在Docker上安裝和運行PHP 7.4

幸運的是,您不需要手動編譯和配置PHP 7.4。如果您已在系統上安裝了Docker,則只需安裝非官方的PHP-FPM 7.4 Docker Image,並在幾秒鐘內從命令行運行測試。

安裝Nginx Docker鏡像

安裝Nginx Docker鏡像

如果您更喜歡在瀏覽器中運行PHP 7.4代碼,還需要安裝Nginx或Apache映像。但不用擔心。只需按照開發人員的指示操作即可。將Docker Image頁面中的命令複製並粘貼到命令行工具中,您就可以開始使用了。

摘要

在這篇文章中,我們介紹了PHP 7.4發布後我們可以期待的大量更改和補充。如果您正在尋找完整的功能列表以及官方RFC文檔,請查看以下資源:

  • PHP 7.4請求注釋
  • PHP 7.4升級說明
  • PHP 7.4準備任務

我們將為您提供有關PHP 7.4及其發布的所有最新信息的最新信息。

你準備好測試即將推出的PHP功能嗎?哪一個是你的最愛?在下面的評論中與我們分享您的想法。

相關文章