目錄
新功能
聯合類型
#JIT
屬性
新增 static 回傳類型
新增mixed 類型
#string
  不僅可以用來作為傳回類型,還可以用作參數和屬性類型。 另外,還要注意,因為
允许对对象使用 ::class
Non-capturing catches
参数列表中的尾部逗号
从接口创建DateTime 对象
新增 Stringable接口
新增 str_contains() 函数 rfc
新增 str_starts_with() 和 str_ends_with() 函数
新增 fp() 函数
新增 get_debug_type() 函数
新增 get_resource_id() 函数
Traits 改进中的抽象方法
token_get_all() rfc的对象实现
可变语法调整 
内部函数的类型注解
重大变化
一致的类型错误 rfc
重新分类的引擎警告 rfc
@ 运算符不再使致命错误不提醒
默认错误报告级别
默认 PDO 错误模式 rfc
串联优先级 rfc
更严格的算术和位运算类型检查
反射方法签名变更
几个弃用
首頁 後端開發 PHP8 PHP 8 中新功能以及重大調整

PHP 8 中新功能以及重大調整

Jun 30, 2020 am 11:32 AM
php php8

PHP 8 中新功能以及重大調整

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

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

  • #float

  • null

  • object

resource

#string

#string

請注意,

mixed

  不僅可以用來作為傳回類型,還可以用作參數和屬性類型。 另外,還要注意,因為

mixed

  類型已經包含了 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);
登入後複製

Non-capturing catches

在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()现在有一种通用的方法可以将DateTimeDatetimeImmutable对象相互转换。

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-INFNAN

新增 get_debug_type() 函数

get_debug_type()返回变量的类型,听起来好像跟 gettype() 的作用一样啊?get_debug_type()  可以为数组,字符串,匿名类和对象返回更有用的输出信息。

例如,在类\ Foo \ Bar上调用gettype()将返回object,而使用get_debug_type()将返回类名。

如下表:

##「你好」字串[]數組nullnullNULL##一個名為「的類別」 Foo\Bar」#匿名類別一個資源##一個已關閉的資源資源(已關閉)#

可以在RFC中找到get_debug_type()gettype()之间的差异的完整列表。

新增 get_resource_id() 函数

资源是PHP中的特殊变量,指的是外部资源。一个示例是MySQL连接,另一个是文件句柄。

这些资源中的每一个都分配有一个ID,然而在这之前,如果想获取某资源的ID,唯一方法是将资源转换为int

$resourceId = (int) $resource;
登入後複製

PHP 8添加了get_resource_id()函数,使此操作更加明显且类型安全:

$resourceId = get_resource_id($resource);
登入後複製

Traits 改进中的抽象方法

Traits  可以指定必须由使用它们的类所实现的抽象方法。需要注意的是: 在 PHP 8 之前,尚未验证这些方法已经实现的标识。以下内容有效:

trait Test {
    abstract public function test(int $input): int;
}

class UsesTrait
{
    use Test;

    public function test($input)
    {
        return $input;
    }
}
登入後複製

当使用 Traits 并实现其抽象方法时,PHP 8将执行适当的方法进行标识验证抽象方法是否确实被实现。这意味着您需要编写以下代码:

class UsesTrait
{
    use Test;

    public function test(int $input): int
    {
        return $input;
    }
}
登入後複製

token_get_all() rfc的对象实现

token_get_all()函数返回一个值数组,该RFC使用PhpToken :: getAll()方法新增了PhpToken类。此实现适用于对象而不是普通值。它消耗更少的内存,并且更易于阅读。

可变语法调整 

在RFC中:“统一变量语法RFC解决了PHP变量语法中的许多不一致之处。该RFC旨在解决一小部分被忽略的情况。”

内部函数的类型注解

许多人 投入 了为所有内部函数添加适当的类型注释的工作。这是一个长期存在的问题,最终可以通过以前版本中对PHP所做的所有更改来解决。这意味着内部函数和方法将在反射中具有完整的类型信息。

重大变化

如前所述:这是一个重大更新,因此会有重大变化。最好的办法是查看 升级  文档中所列的重大变化的完整列表。

许多这些突破性的更改在以前的 7.* 版本中已被弃用,因此如果你多年来一直保持 PHP 在最新状态,升级到 PHP 8 应该没那么难。

一致的类型错误 rfc

之前版本在出现类型错误时,PHP 中的用户定义函数已经会抛出 TypeErrors,但是内部函数不会这么做,而是发出警告并返回 null。从 PHP 8 开始,内部函数的行为已变得和用户定义函数一致。

重新分类的引擎警告 rfc

许多以前仅触发警告或通知的错误已转换为适当的错误。以下警告已更改。

  • 变量未定义:Error 异常代替通知

  • 数组索引未定义:警告代替通知

  • 除以零:pisionByZeroError 异常代替警告

  • 尝试添加/移除非对象的属性 '%s' :Error 异常代替警告

  • 尝试修改非对象的属性 '%s' :Error 异常代替警告

  • 尝试分配非对象的属性 '%s' :Error 异常代替警告

  • 从空值创建默认对象:Error 异常代替警告

  • 尝试获取非对象的属性 '%s' :警告代替通知

  • 未定义的属性:%s::$%s:警告代替通知

  • 无法添加元素到数组,因为下一个元素已被占用:Error 异常代替警告

  • 无法在非数组变量中销毁偏移量:Error 异常代替警告

  • 无法将标量值用作数组:Error 异常代替警告

  • 只有数组和 Traversables 可以被解包:TypeError 异常代替警告

  • 为 foreach() 提供了无效的参数:TypeError 异常代替警告

  • 偏移量类型非法:TypeError 异常代替警告

  • isset 或 empty 中的偏移量类型非法:TypeError 异常代替警告

  • unset 中的偏移量类型非法:TypeError 异常代替警告

  • 数组到字符串的转换:警告代替通知

  • 资源 ID#%d 用作偏移量,转换为整数 (%d):警告代替通知

  • 发生字符串偏移量转换:警告代替通知

  • 未初始化的字符串偏移量:%d:警告代替通知

  • 无法将空字符串分配给字符串偏移量:Error 异常代替警告

  • 提供的资源不是有效的流资源:TypeError 异常代替警告

@ 运算符不再使致命错误不提醒

此更改可能会使 PHP 8 之前的版本被 @ 隐藏的错误再次显示出来。请确保在生产服务器上设置了 display_errors=Off !

默认错误报告级别

现在的默认错误报告级别是 E_ALL 而不是之前的除 E_NOTICE 和 E_DEPRECATED 的所有内容。这意味着可能会弹出许多错误,这些错误以前曾被忽略,尽管在 PHP 8 之前的版本中可能已经存在。

默认 PDO 错误模式 rfc

根据RFC:当前 PDO 的默认错误模式为静默。这意味着当出现 SQL 错误时,除非开发人员实现了自己的显式错误处理,否则不会发出任何错误或警告,也不会引发任何异常。

此 RFC 将在 PHP 8 中将默认 PDO 错误模式 改为PDO::ERRMODE_EXCEPTION 。

串联优先级 rfc

在 PHP 7.4 中已废弃的同时,此变更开始生效。如果你像这样子书写:

echo "sum: " . $a + $b;
登入後複製

PHP 以前会如是理解:

echo ("sum: " . $a) + $b;
登入後複製

PHP 8 将这么做故理解为此:

echo "sum: " . ($a + $b);
登入後複製

更严格的算术和位运算类型检查

PHP 8 以前,算术或位运算符用于数组、资源或对象是可接受的。现在不再可接受,并会抛出一个 类型错误

[] % [42];
$object + 4;
登入後複製

反射方法签名变更

反射类的 3 个方法签名已变更:

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 7. * 的开发期间,添加了几个弃用版本,这些弃用已于 PHP 8 最终确定。

  • PHP 7.2 中的弃用
  • PHP 7.3 中的弃用
  • PHP 7.4 中的弃用
get_debug_type() #gettype()
0 int 整數
0.1 浮點 雙精確度
#true bool boolean
#false bool boolean


Foo\Bar 物件
class@anonymous object
resource (xxx) resource

以上是PHP 8 中新功能以及重大調整的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡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

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

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

熱門話題

Java教學
1662
14
CakePHP 教程
1418
52
Laravel 教程
1311
25
PHP教程
1261
29
C# 教程
1234
24
您如何在PHP中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

解釋PHP中的晚期靜態綁定(靜態::)。 解釋PHP中的晚期靜態綁定(靜態::)。 Apr 03, 2025 am 12:04 AM

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

php程序在字符串中計數元音 php程序在字符串中計數元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? 什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? Apr 03, 2025 am 12:03 AM

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。

PHP和Python:比較兩種流行的編程語言 PHP和Python:比較兩種流行的編程語言 Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP行動:現實世界中的示例和應用程序 PHP行動:現實世界中的示例和應用程序 Apr 14, 2025 am 12:19 AM

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

See all articles