搜尋
首頁後端開發PHP7PHP 8 還有半年就要來了, 來看看有哪些新特性

PHP 8 還有半年就要來了, 來看看有哪些新特性

新的 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);

推荐教程:《PHP教程

以上是PHP 8 還有半年就要來了, 來看看有哪些新特性的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:learnku。如有侵權,請聯絡admin@php.cn刪除

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版