PHP 8.3 引入了許多值得關(guān)注的新特性和改進(jìn),可以使代碼更安全、更簡(jiǎn)潔、性能更好。下面是一些關(guān)鍵的新特性(以及相關(guān)變更):
核心新特性
1. 類型化類常量(Typed Class Constants)
在 PHP 8.3 之前,常量(const
)不能聲明類型。8.3 允許在類、接口、trait 和 enum 的常量上指定類型。 (PHP)
class Foo {
public const string VERSION = "1.0";
}
interface I {
const int MAX = 100;
}
- 如果在基類/接口中聲明了常量類型,那么子類/實(shí)現(xiàn)類在重寫常量時(shí)也必須保持兼容類型。 (Kinsta®)
- 允許使用聯(lián)合類型(如 string|int)來聲明常量類型。 (Kinsta®)
2. 動(dòng)態(tài)訪問類常量/枚舉成員(Dynamic Constant Fetch)
在 PHP 8.3,你可以用類似 C::{$name}
的語(yǔ)法動(dòng)態(tài)訪問類常量或枚舉成員,替代過去經(jīng)常用的 constant()
函數(shù)。 (PHP)
class Foo {
public const BAR = 123;
}
$name = "BAR";
echo Foo::{$name}; // 123
3. 只讀屬性的深拷貝(Deep Cloning of readonly
Properties)
PHP 從 8.1 開始支持 readonly
屬性,從 8.2 開始支持將整個(gè)類標(biāo)記為 readonly
。在 8.3 中,對(duì) readonly
特性做了重要增強(qiáng):當(dāng)對(duì)含有 readonly
屬性的對(duì)象進(jìn)行克?。?code>clone)時(shí),可以在 __clone()
魔術(shù)方法中重新初始化這些屬性。即,readonly
屬性在克隆時(shí)可被賦值一次,從而支持“深拷貝”場(chǎng)景。 (PHP)
class A {
public string $value;
}
readonly class B {
public function __construct(
public A $a
) {}
public function __clone(): void {
$this->a = clone $this->a;
}
}
$b1 = new B(new A());
$b2 = clone $b1;
$b2->a->value = "changed"; // 合法
此外,匿名類現(xiàn)在也可以被標(biāo)記為 readonly
。 (PHP)
4. 新函數(shù) json_validate()
為了解決在只想驗(yàn)證 JSON 字符串是否合法時(shí)不得不用 json_decode()
帶來額外內(nèi)存開銷的問題,PHP 8.3 引入了 json_validate()
。該函數(shù)只驗(yàn)證 JSON 的語(yǔ)法是否合法,不生成對(duì)象/數(shù)組。 (PHP)
if (json_validate($jsonString)) {
// 是合法 JSON
}
你也可以傳入深度和 flags 參數(shù)。 (PHP)
5. Random 擴(kuò)展增強(qiáng)(Randomizer 新方法)
PHP 的 Random 擴(kuò)展在此前版本就已經(jīng)引入,8.3 在其基礎(chǔ)上做了增強(qiáng):加入了一些新的方法:
- getBytesFromString(string $str, int $length):從給定字符串隨機(jī)選取字節(jié)生成指定長(zhǎng)度的字符串。 (PHP)
- getFloat() / nextFloat():生成浮點(diǎn)數(shù)隨機(jī)值。你可以指定區(qū)間以及區(qū)間開閉邊界。 (Kinsta®)
6. #[\Override]
特性(Attribute)
PHP 8.3 新增了 #[\Override]
屬性,用于標(biāo)注一個(gè)方法是對(duì)父類或接口方法的覆蓋/重寫。編譯器/檢查器可以據(jù)此幫助捕獲因方法名拼寫錯(cuò)誤而沒有真正覆蓋的情況。 (PHP)
class Base {
public function foo() {}
}
class Child extends Base {
#[\Override]
public function foo() {}
}
如果你寫錯(cuò)成 fao()
,而標(biāo)記了 #[\Override]
,就能在靜態(tài)檢查或運(yùn)行時(shí)報(bào)錯(cuò)。 (Kinsta®)
7. 其他語(yǔ)法 / 函數(shù) /行為變更與增強(qiáng)
PHP 的官方遷移說明里列出了一些次要但實(shí)用的更新: (PHP)
項(xiàng)目 | 描述 |
---|---|
靜態(tài)變量初始化 | 現(xiàn)在靜態(tài)變量(static $x = … )可以使用任意表達(dá)式作為初始值(以前限制更多) |
從魔術(shù)方法創(chuàng)建的閉包支持命名參數(shù) | 在 __call() 、__get() 等魔術(shù)方法中創(chuàng)建閉包時(shí)可以使用命名參數(shù) |
trait 中的方法可以用 final 修飾 | 在 trait 內(nèi)部的方法如果不希望被子類重寫,可以標(biāo)記為 final |
class_alias() 支持為內(nèi)部類創(chuàng)建別名 | 你可以給 PHP 內(nèi)置類起別名,比如 class_alias('DateTime', 'MyDateTime'); |
新函數(shù) stream_context_set_options() | 為 stream contexts 提供更多選項(xiàng)支持 |
增強(qiáng) mb_str_pad() 函數(shù) | 新增多字節(jié)字符串填充支持 |
更細(xì)粒度的 DateTime 異常 | 在處理 DateTime / 日期操作時(shí),異常類型更精細(xì),以便更好捕獲錯(cuò)誤 |
unserialize() 的通知升級(jí) | 以前某些反序列化錯(cuò)誤是 E_NOTICE ,8.3 將升級(jí)為 E_WARNING |
SQLite3 擴(kuò)展的變更 & 棄用 | 一些類和常量做了調(diào)整與棄用 |
CLI Lint 支持多文件檢查 | php -l 可以同時(shí)對(duì)多個(gè)文件進(jìn)行語(yǔ)法檢查 |
INI 環(huán)境變量語(yǔ)法添加 “fallback value” 支持 | 在 php.ini 或環(huán)境變量中使用 var ?: default 形式作為回退值支持 |
gc_status() 函數(shù)增強(qiáng) | 新增更多屬性,顯示垃圾回收運(yùn)行狀態(tài)等詳細(xì)信息 |
棄用某些舊特性 | 比如對(duì)不帶參數(shù)調(diào)用的 get_class() / get_parent_class() 可能被棄用或行為改變;還包括 assert() 與 assert_options() 的字符串?dāng)嘌孕问奖粭売玫?/td> |
遷移和兼容性注意
雖然這些特性多數(shù)向后兼容,但在升級(jí)時(shí)要注意:
- 有些舊寫法或行為可能觸發(fā)新的錯(cuò)誤/警告(尤其是 unserialize()、SQLite3、trait 方法、常量類型不匹配等)。
- 在代碼中使用 #[\Override] 會(huì)幫助捕捉本來因?yàn)槠磳戝e(cuò)誤或方法簽名不匹配而未被覆蓋的方法。
- 對(duì)于 readonly 的深拷貝功能,如果你在 __clone() 邏輯中重寫屬性,要謹(jǐn)慎處理以維護(hù)不變性原則。
- 第三方庫(kù)、擴(kuò)展可能尚未完全適配新版本,升級(jí)前要做好測(cè)試。