PHP 8,PHP 的一個新的大版本,預計將於2020年12月3日發布,這意味著將不會有 PHP 7.5 版本。 PHP8目前正處於非常活躍的開發階段,所以在接下來的幾個月裡,情況可能會發生很大的變化。
在這篇文章中,我會維持一個最新的清單列表,列出預計會出現的新特性、效能提升和突破性的變化。由於 PHP 8 是一個新的大版本,因此您的程式碼被破壞的可能性更高。如果您始終保持運行 PHP 的最新版本,那麼升級相對來說就會輕鬆很多,因為在7. *版本中,大多數重大更改均已棄用。
除重大變更外,PHP 8也帶來了一些不錯的新功能,例如說 JIT編譯器, 聯合類型, 屬性,以及更多。
從新功能開始,請記住 PHP8 仍處於活動開發階段,因此此清單將隨著時間的推移而成長。
考慮到 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 — just in time — 編譯器雖然不總是在Web 請求的上下文中,但是有望顯著地提高效能。目前還沒有完成任何準確的基準測試,但肯定會到來。
如果您想進一步了解JIT對PHP的作用,可以閱讀我寫過的另一篇文章此處。
屬性在其他語言中通常被稱為註解 ,提供一種在無需解析文件區塊的情況下將元數據添加到類別中的方法。
快速瀏覽一下,這裡有一份來自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
回傳類型#儘管已經可以回傳self
,但是static
直到PHP 8 是有效的回傳類型。考慮到 PHP 具有動態類型的性質,此功能對於許多開發人員將非常有用。
class Foo { public function test(): static { return new static(); } }
mixed
類型#有人可能稱之為必要的邪惡:mixed
類型讓許多人感覺十分混亂。然而,有一個很好的論點支持去實現它:缺少類型在PHP 中會導致很多情況:
#函數不會傳回任何內容或傳回空值
我們需要多種類型的一種類型
我們需要的是PHP中不能進行類型提示的類型
#因為上述原因,新增mixed
類型是一件很棒的事兒。 mixed
本身就代表下列型別中的任一型別:
array
# #bool
callable
#int
#string
#string請注意,
類型已經包含了 null
,因此 mixed
類型不可為空。下面的程式碼會觸發致命錯誤:
// 致命错误:混合类型不能为空,null已经是混合类型的一部分。 function bar(): ?mixed {}###throw### 表達式#########該RFC將###throw###從一個語句更改為一個表達式,這使得可以在許多新地方拋出異常:###
$triggerError = fn () => throw new MyError(); $foo = $bar['offset'] ?? throw new OffsetDoesNotExist('offset');######弱映射#########基於在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
一个很小但是很有用的新特性:现在可以在对象上使用 :: class
,而不必在对象上使用 get_class()
,它的工作方式跟 get_class()
相同。
$foo = new Foo(); var_dump($foo::class);
在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
作为捕获类型。
当调用函数时已经支持尾部逗号,但是参数列表中仍然缺少尾随逗号支持。现在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
接口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()
函数这是另外两个早该出现的函数,现在已在核心函数中添加了这两个函数。
str_starts_with('haystack', 'hay'); // true str_ends_with('haystack', 'stack'); // true
fp()
函数新的fp()
函数的作用类似于fmod()
和intp()
函数,它们可以除以0。视情况而定,将得到INF
,-INF
或NAN
。
get_debug_type()
函数get_debug_type()
返回变量的类型,听起来好像跟 gettype()
的作用一样啊?get_debug_type()
可以为数组,字符串,匿名类和对象返回更有用的输出信息。
例如,在类\ Foo \ Bar
上调用gettype()
将返回object
,而使用get_debug_type()
将返回类名。
如下表:
值 | get_debug_type() | #gettype() |
---|---|---|
0 | int | 整數 |
0.1 | 浮點 | 雙精確度 |
#true | bool | boolean |
#false | bool | boolean |
字串 | ||
數組 | ||
null | NULL | |
Foo\Bar | 物件 | |
class@anonymous | object | |
resource (xxx) | resource | ##一個已關閉的資源 |
以上是PHP 8 中新功能以及重大調整的詳細內容。更多資訊請關注PHP中文網其他相關文章!