新的 PHP 主要版本 PHP8 預計將于 2020 年底發布,
它現在正處于非常活躍的開發中,所以在接下來的幾個月里,開發速度和開發行程可能會有很大的變化,
官方群點擊此處,
在這篇文章中,我會羅列出 PHP8 中會發生的一些改變:新功能、性能改進和突破性變化,
因為 PHP8 是一個新的主要版本,所以代碼及語法向下兼容性會更低,
如果您一直保持與最新版本保持同步,那么升級應該不會太難,因為大多數突破性的更改在 7.* 版本中都已棄用,
除了突破性的變化,PHP8 還帶來了一些不錯的新特性,比如 JIT 編譯器和 union types,當然還有其它更多的特性,
新特性
從新特性開始說起,但是 PHP8 仍在積極開發中,因此這個清單將隨著時間的推移而增長,
聯合型別 (Union types) RFC
考慮到 PHP 的動態型別特性,聯合型別在很多情況下都很有用,
聯合型別是兩個或多個型別的集合,這些型別指示可以使用這兩個型別中的任何一個,
public function foo(Foo|Bar $input): int|float;
我怎么感覺這個和 C 語言里的聯合體有點相似,
請注意,void 永遠不能是聯合型別的一部分,因為它表示 “根本沒有回傳值”,
此外,可以使用 |NULL 或使用現有的?,
public function foo(Foo|null $foo): void;
public function bar(?Bar $bar): void;
JIT RFC
JIT-Just-In-Time 編譯器承諾顯著提高性能,盡管在 Web 應用可能沒有較大的好處,
在這一點上還沒有任何準確的基準,但它們肯定會出現的,
靜態回傳型別 (Static return type) RFC
雖然已經可以回傳 self ,但在 PHP8 之前,靜態不是有效的回傳型別,考慮到 PHP 的動態型別特性,它對許多開發人員都很有用,
class Foo
{
public function test(): static
{
return new static();
}
}
弱映射 (Weak maps) RFC
基于在 PHP 7.4 中添加的 WeakRefs RFC 的基礎上,在 PHP 8 中 添加了 WeakMap 實作,WeakMap 包含對物件的參考,這不會阻止這些物件被垃圾回收,
以 ORM 為例,它們經常實作包含對物體類的參考的快取,以提高物體之間關系的性能,
這些物體物件不能被垃圾回收,只要該快取有對它們的參考,即使快取是唯一參考它們的東西,
如果該快取層改為使用弱參考和映射,則 PHP 將在其他物件不再參考這些物件時對它們進行垃圾回收,
特別是在 ORM 的情況下,它可以在一個請求中管理數百個 (如果不是數千個) 物體;弱映射可以提供一種更好、更資源友好的方式來處理這些物件,
以下是 Weak maps 的用法,RFC 中的一個示例:
class Foo
{
private WeakMap $cache;
public function getSomethingWithCaching(object $obj): object
{
return $this->cache[$obj]
??= $this->computeSomethingExpensive($obj);
}
}
可以在物件上使用::class RFC
一個小而有用的新特性:現在可以對物件使用::class,而不必對它們使用 get_class(),
它的作業方式與 get_class() 相同,
$foo = new Foo();
var_dump($foo::class);
創建 DateTime 物件的介面
您已經可以使用 DateTime::createFromImmutable($immutableDateTime),從 DateTimeImmutable 物件創建 DateTime 物件,但是反過來很棘手,
通過添加 DateTime::createFromInterface() 和 DatetimeImmutable::createFromInterface(),現在有了一種將 DateTime 和 DateTimeImmutable 物件相互轉換的通用方法,
DateTime::createFromInterface(DateTimeInterface $other);
DateTimeImmutable::createFromInterface(DateTimeInterface $other);
新的 Stringable 介面 RFC
Stringable 介面可用于鍵入提示任何字串或實作__toString(),
此外,每當類實作__toString() 時,它都會自動在幕后實作介面,不需要手動實作它,
class Foo
{
public function __toString(): string
{
return 'foo';
}
}
function bar(Stringable $stringable) { /* … */ }
bar(new Foo());
bar('abc');
新的 str_contains () 函式 RFC
有些人可能會說這是早就應該實作的功能,但是我們最終不必再依賴 strpos () 來知道一個字串是否包含另一個字串,
以前:
if (strpos('string with lots of words', 'words') !== false) { /* … */ }
現在:
if (str_contains('string with lots of words', 'words')) { /* … */ }
新的 fdiv () 函式 PR
新的 fdiv () 函式的作用類似于 fmod () 和 intdiv () 函式,它們允許被 0 整除,
您將得到 INF、-INF 或 NaN ,而不是錯誤,具體取決于大小寫,
新的 get_debug_type () 函式 RFC
- get_debug_type () 回傳一個變數的型別,
- 聽起來像是 gettype () 可以實作的功能,
- get_debug_type () 為陣列、字串、匿名類和物件回傳更有用的輸出,
- 例如,在類 \foo\Bar 上呼叫 gettype () 將回傳 Object,
- 使用 get_debug_type () 將回傳類名,
- 可以在 RFC 中找到 get_debug_type () 和 gettype () 之間差異的完整串列,
改進 traits 里的抽象方法 RFC
traits 可以指定必須由使用它們的類實作的抽象方法,
但是有一個警告:在 PHP8 之前,這些方法實作的簽名沒有經過驗證,
在以下代碼中有效:
trait Test {
abstract public function test(int $input): int;
}
class UsesTrait
{
use Test;
public function test($input)
{
return $input;
}
}
在使用 traits 并實作其抽象方法時,PHP8 將執行正確的方法簽名驗證,
這意味著您需要改寫以下內容:
class UsesTrait
{
use Test;
public function test(int $input): int
{
return $input;
}
}
token_get_all () 的物件介面 RFC
函式的作用是:回傳值的是一個陣列,
此 RFC 使用 PhpToken::getall () 方法添加一個 PhpToken 類,
此實作使用物件,而不是普通值,
它消耗更少的記憶體,更容易閱讀,
變數語法調整 RFC
來自 RFC:“統一變數語法 RFC 解決了 PHP 變數語法中的一些不一致問題”,這個 RFC 打算解決少數被忽略的情況,
內部函式的型別批注
很多人都參與到為所有內部函式添加適當型別注釋的作業中,
這是一個長期存在的問題,通過在以前版本中對 PHP 所做的所有更改,最終可以解決這個問題,
這意味著內部函式和方法在反射中將具有完整的型別資訊,
統一錯誤型別 RFC
PHP 中的用戶定義函式已經拋出 TypeErrors,但是內部函式沒有拋出 TypeErrors,而是發出警告并回傳 NULL,
從 PHP8 開始,內部函式的行為已經保持一致,
重新分類 zend engine 報錯 RFC
許多以前只觸發警告或通知的錯誤已轉換為適當的錯誤,
以下警告已更改,
未定義變數:錯誤例外而不是通知,
未定義的陣列索引:警告而不是通知,
被零除:DivisionByZeroError 例外而不是警告,
嘗試遞增 / 遞減非物件的屬性‘% s’:錯誤例外而不是警告,
試圖修改非物件的屬性‘% s’:錯誤例外而不是警告,
嘗試分配非物件的屬性‘% s’:錯誤例外而不是警告,
從空值創建默認物件:錯誤例外而不是警告,
正在嘗試獲取非物件的屬性‘% s’:警告而不是通知,
未定義屬性:% s::$% s:警告而不是通知,
無法將元素添加到陣列,因為下一個元素已被占用:錯誤例外而不是警告,
無法取消設定非陣列變數中的偏移量:錯誤例外而不是警告,
不能將標量值用作陣列:錯誤例外而不是警告,
只能解包陣列和遍歷:TypeError 例外而不是警告,
為 foreach () 提供的引數無效:TypeError 例外而不是警告,
偏移型別非法:TypeError 例外而不是警告,
isset 中的偏移型別非法或為空:TypeError 例外而不是警告,
未設定中的偏移型別非法:TypeError 例外而不是警告,
陣列到字串的轉換:警告而不是通知,
資源 ID#% d 用作偏移量,轉換為整數 (% d):警告而不是通知,
發生字串偏移量轉換:警告而不是通知,
未初始化的字串偏移量:% d:警告而不是通知,
無法將空字串分配給字串偏移量:錯誤例外而不是警告
默認錯誤報告級別
現在是 E_ALL,而不是除 E_NOTICE 和 E_DEVERATED 之外的所有內容,
這意味著可能會彈出許多以前被悄悄忽略的錯誤,盡管在 PHP8 之前可能已經存在,
@運算子不再忽略致命錯誤
此更改可能會揭示在 PHP8 之前隱藏的錯誤,請確保在生產服務器上設定 display_errors=off !
串聯優先級 RFC
雖然在 PHP7.4 中已不推薦使用,但此更改現在生效,
如果你這樣寫的話:
echo "sum: " . $a + $b;
PHP 以前會這樣解釋它:
echo ("sum: " . $a) + $b;
PHP 8 將會這樣解釋它:
echo "sum: " . ($a + $b);
反射方法簽名更改
反射類的三個方法簽名已更改:
ReflectionClass::newInstance($args);
ReflectionFunction::invoke($args);
ReflectionMethod::invoke($object, $args);
現已成為:
ReflectionClass::newInstance(...$args);
ReflectionFunction::invoke(...$args);
ReflectionMethod::invoke($object, ...$args);
升級指南指定,如果您擴展了這些類,并且仍然希望同時支持 PHP 7 和 PHP 8,則允許以下簽名:
ReflectionClass::newInstance($arg = null, ...$args);
ReflectionFunction::invoke($arg = null, ...$args);
ReflectionMethod::invoke($object, $arg = null, ...$args);
更多學習內容請訪問:
騰訊T3-T4標準精品PHP架構師教程目錄大全,只要你看完保證薪資上升一個臺階(持續更新)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/33647.html
標籤:PHP
上一篇:PHP正則運算式語法匯總
