PHP 8釋出啦!來說說PHP 8 的新特性
PHP 8,PHP 的一個新的大版本,預計將於 2020 年 12 月 3 日釋出,這意味著將不會有 PHP 7.5 版本。PHP8 目前正處於非常活躍的開發階段,所以在接下來的幾個月裡,情況可能會發生很大的變化。
在這篇文章中,我會維持一個最新的清單列表,列出預計會出現的新特性、效能提升和突破性的變化。由於 PHP 8 是一個新的大版本,因此您的程式碼被破壞的可能性更高。如果您始終保持執行 PHP 的最新版本,那麼升級相對來說就會輕鬆很多,因為在 7. * 版本中,大多數重大更改均已棄用。
除重大更改外,PHP 8 還帶來了一些不錯的新功能,比如說 JIT 編譯器 , 聯合型別 , 屬性,以及更多。
新特性
從新特性開始,請記住 PHP8 仍處於活動開發階段,因此此列表將隨著時間的推移而增長。
聯合型別 rfc
考慮到 PHP 動態語言型別的特性,現在很多情況下,聯合型別都是很有用的。聯合型別是兩個或者多個型別的集合,表示可以使用其中任何一個型別。
public function foo(Foo|Bar $input): int|float;
請注意,聯合型別中不包含 void
,因為 void
表示的含義是 “根本沒有返回值”。 另外,可以使用 |null
或者現有的 ?
表示法來表示包含 nullable
的聯合體 :
public function foo(Foo|null $foo): void; public function bar(?Bar $bar): void;
JIT rfc
JIT — just in time — 編譯器雖然不總是在 Web 請求的上下文中,但是有望顯著地提高效能。目前還沒有完成任何準確的基準測試,但是肯定會到來。
如果您想進一步瞭解 JIT 對 PHP 的作用,可以閱讀我寫過的另一篇文章此處。
屬性 rfc
屬性在其他語言中通常被稱為 註解 ,提供一種在無需解析文件塊的情況下將元資料新增到類中的方法。
快速瀏覽一下,這裡有一份來自 RFC 的屬性示例:
use App\Attributes\ExampleAttribute; <<ExampleAttribute>> class Foo { <<ExampleAttribute>> public const FOO = 'foo'; <<ExampleAttribute>> public $x; <<ExampleAttribute>> public function foo(<<ExampleAttribute>> $bar) { } }
<<PhpAttribute>>
class ExampleAttribute
{
public $value;
public function __construct($value)
{
$this->value = $value;
}
}
如果您想深入瞭解屬性如何工作以及如何構建自己的屬性,您可以在此部落格上閱讀有關深入屬性的資訊。
新增 static
返回型別 rfc
儘管已經可以返回 self
,但是 static
直到 PHP 8 才是有效的返回型別 。考慮到 PHP 具有動態型別的性質,此功能對於許多開發人員將非常有用。
class Foo
{
public function test(): static
{
return new static();
}
}
新增 mixed
型別 rfc
有人可能將其稱為必要的邪惡:mixed
型別讓許多人感覺十分混亂。然而,有一個很好的論據支援去實現它:缺少型別在 PHP 中會導致很多情況:
-
函式不返回任何內容或返回空值
-
我們需要多種型別的一種型別
-
我們需要的是 PHP 中不能進行型別提示的型別
因為上述原因,新增 mixed
型別是一件很棒的事兒。mixed
本身代表下列型別中的任一型別:
-
array
-
bool
-
callable
-
int
-
float
-
null
-
object
-
resource
-
string
請注意,mixed
不僅僅可以用來作為返回型別,還可以用作引數和屬性型別。
另外,還需要注意,因為 mixed
型別已經包括了 null
,因此 mixed
型別不可為空。下面的程式碼會觸發致命錯誤:
// 致命錯誤:混合型別不能為空,null已經是混合型別的一部分。
function bar(): ?mixed {}
throw
表示式 rfc
該 RFC 將 throw
從一個語句更改為一個表示式,這使得可以在很多新地方丟擲異常:
$triggerError = fn () => throw new MyError();
$foo = $bar['offset'] ?? throw new OffsetDoesNotExist('offset');
弱對映 rfc
基於在 PHP 7.4 中新增的 弱引用 RFC,PHP 8 中新增了 WeakMaps
(弱對映)的實現。 WeakMaps
(弱對映)在保持對一些物件的引用的同時,並不會組織這些物件被垃圾回收機制處理 。
以 ORM 為例,它們通常實現儲存對實體類的引用的快取,從而提高實體類之間關聯的效能。 只要快取中存在對這些實體類的引用,那麼這些類就無法被垃圾回收機制回收,儘管除了快取中,已經沒有別處再引用這些實體類,它們依然不會被垃圾處理機制處理。
如果這個快取層使用了弱引用和弱對映,那麼 PHP 將會在這些實體類沒有任何其他引用時,對其進行垃圾回收。 尤其是對於 ORMs,它可以管理一個請求中的數百個 (如果不是數千個) 實體;弱對映可以提供一種更好的、對資源更友好的方式來處理這些物件。
下面是弱對映基本的例子,摘抄自 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);
Non-capturing catches rfc
在 PHP 8 之前,無論何時你想要捕獲一個異常,你都需要先將其儲存到一個變數中,不管這個變數你是否會用到。通過 Non-capturing catches
你可以忽略變數,所以替換下面的程式碼:
try {
// Something goes wrong
} catch (MySpecialException $exception) {
Log::error("Something went wrong");
}
你現在可以這麼做:
try {
// Something goes wrong
} catch (MySpecialException) {
Log::error("Something went wrong");
}
請注意,必須始終指定型別,不允許將 catch 留空,如果你想要捕獲所有型別的異常和錯誤,需要使用 Throwable 作為捕獲型別。
引數列表中的尾部逗號 rfc
當呼叫函式時已經支援尾部逗號,但是引數列表中仍然缺少尾隨逗號支援。現在 PHP8 中允許這樣做,這意味著您可以執行以下操作:
public function(
string $parameterA,
int $parameterB,
Foo $objectfoo,
) {
// …
}
從介面建立 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')) { /* … */ }
新增 str_starts_with()
和 str_ends_with()
函式 rfc
這是另外兩個早該出現的函式,現在已在核心函式中添加了這兩個函式。
str_starts_with('haystack', 'hay'); // true
str_ends_with('haystack', 'stack'); // true
點關注,不迷路
好了各位,以上就是這篇文章的全部內容了,能看到這裡的人呀,都是人才。之前說過,PHP方面的技術點很多,也是因為太多了,實在是寫不過來,寫過來了大家也不會看的太多,所以我這裡把它整理成了PDF和文件,如果有需要的可以
更多學習內容可以訪問【對標大廠】精品PHP架構師教程目錄大全,只要你能看完保證薪資上升一個臺階(持續更新)
以上內容希望幫助到大家,很多PHPer在進階的時候總會遇到一些問題和瓶頸,業務程式碼寫多了沒有方向感,不知道該從那裡入手去提升,對此我整理了一些資料,包括但不限於:分散式架構、高可擴充套件、高效能、高併發、伺服器效能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell指令碼、Docker、微服務、Nginx等多個知識點高階進階乾貨需要的可以免費分享給大家,需要的可以加入我的 PHP技術交流群