-
match
現在是保留關鍵字。
-
mixed
現在是保留字,因此不能用於命名類別、介面或特性,並且也禁止在命名空間中使用。
-
現在預設會擲出斷言失敗的例外。如果需要舊的行為,可以在 INI 設定中設定 assert.exception=0
。
-
與類別名稱相同的方法不再被解釋為建構子。應使用 __construct() 方法。
-
已移除靜態呼叫非靜態方法的功能。因此,使用類別名稱檢查非靜態方法時,is_callable() 將會失敗(必須使用物件實例檢查)。
-
已移除 (real)
和 (unset)
轉型。
-
已移除 track_errors ini 指令。這表示 php_errormsg 不再可用。可以使用 error_get_last() 函式替代。
-
已移除定義大小寫不敏感常數的功能。 define() 的第三個參數不能再是 true
。
-
已移除使用 __autoload() 函式定義自動載入器的功能。應使用 spl_autoload_register() 。
-
errcontext
參數將不再傳遞給使用 set_error_handler() 設定的自訂錯誤處理程式。
-
已移除 create_function()。可以使用匿名函式替代。
-
已移除 each()。應使用 foreach 或 ArrayIterator。
-
已移除使用 Closure::fromCallable() 或 ReflectionMethod::getClosure() 從方法建立的閉包中解除繫結 this 的功能。
-
也已移除從包含 this 用法的正式閉包中解除繫結 this 的功能。
-
已移除將 array_key_exists() 與物件一起使用的功能。可以使用 isset() 或 property_exists() 替代。
-
array_key_exists() 關於 key
參數類型的行為已與 isset() 和一般陣列存取保持一致。現在所有鍵類型都使用一般的強制轉換,而陣列/物件鍵會擲出 TypeError。
-
任何第一個數字鍵為數字 n 的陣列,其下一個隱含鍵將使用 n+1,即使 n 為負數也是如此。
-
預設的 error_reporting 等級現在是 E_ALL
。先前它不包含 E_NOTICE
和 E_DEPRECATED
。
-
display_startup_errors 現在預設為啟用。
-
在沒有父類別的類別中使用 parent 現在會導致致命的編譯時期錯誤。
-
`@` 運算符將不再抑制致命錯誤(E_ERROR
、E_CORE_ERROR
、E_COMPILE_ERROR
、E_USER_ERROR
、E_RECOVERABLE_ERROR
、E_PARSE
)。預期在使用 `@` 時 `error_reporting` 為 `0` 的錯誤處理器,應調整為使用遮罩檢查。
<?php
// 將
function my_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() == 0) {
return false;
}
// ...
}
// 替換成
function my_error_handler($err_no, $err_msg, $filename, $linenum) {
if (!(error_reporting() & $err_no)) {
return false;
}
// ...
}
?>
此外,應注意不要在正式環境中顯示錯誤訊息,這可能會導致資訊洩漏。請確保將 `display_errors=Off` 與錯誤日誌記錄一起使用。
-
`#[` 不再被解釋為註釋的開頭,因為此語法現在用於屬性。
-
由於不相容的方法簽章(違反 LSP 原則)所導致的繼承錯誤現在將始終產生致命錯誤。以前在某些情況下會產生警告。
-
字串串接運算符的優先順序相對於位元位移、加法和減法已更改。
<?php
echo "Sum: " . $a + $b;
// 之前的解釋為:
echo ("Sum: " . $a) + $b;
// 現在的解釋為:
echo "Sum:" . ($a + $b);
?>
-
執行階段解析為 null
的預設值參數將不再隱式地將參數類型標記為可空值。必須改用明確的可空值類型或明確的 null
預設值。
<?php
// 將以下程式碼
function test(int $arg = CONST_RESOLVING_TO_NULL) {}
// 替換為
function test(?int $arg = CONST_RESOLVING_TO_NULL) {}
// 或是
function test(int $arg = null) {}
?>
-
一些警告已轉換為 Error 例外。
- 嘗試寫入非物件的屬性。先前,這會針對 null、false 和空字串隱式建立 stdClass 物件。
- 嘗試將元素附加到已使用 PHP_INT_MAX 作為鍵值的陣列。
- 嘗試使用無效類型(陣列或物件)作為陣列鍵值或字串偏移量。
- 嘗試寫入純量值的陣列索引。
- 嘗試解包非陣列/Traversable 的值。
- 嘗試存取未定義的非限定常數。先前,存取未定義的非限定常數會產生警告並被解釋為字串。
- 將錯誤數量的參數傳遞給非可變參數數量內建函式將會拋出 ArgumentCountError。
- 將無效的可計數類型傳遞給 count() 將會拋出 TypeError。
一些通知已轉換為警告。
- 嘗試讀取未定義的變數。
- 嘗試讀取未定義的屬性。
- 嘗試讀取未定義的陣列鍵值。
- 嘗試讀取非物件的屬性。
- 嘗試存取非陣列的陣列索引。
- 嘗試將陣列轉換為字串。
- 嘗試使用資源作為陣列鍵值。
- 嘗試使用 null、布林值或浮點數作為字串偏移量。
- 嘗試讀取超出界限的字串偏移量。
- 嘗試將空字串賦值給字串偏移量。
-
嘗試將多個位元組賦值給字串偏移量現在會發出警告。
-
原始程式碼檔案中的非預期字元(例如字串以外的 NUL 位元組)現在將導致 ParseError 例外,而不是編譯警告。
-
未攔截的例外現在會經歷「乾淨關閉」,這表示在未攔截的例外之後會呼叫解構函式。
-
編譯時期的致命錯誤「只能傳遞變數作為參考」已延遲到執行階段,並轉換為「參數不能作為參考傳遞」的 Error 例外。
-
一些「應該只傳遞變數作為參考」的通知已轉換為「參數不能作為參考傳遞」的例外。
-
匿名類別的產生名稱已更改。它現在將包含第一個父類別或介面的名稱。
<?php
new class extends ParentClass {};
// -> ParentClass@anonymous
new class implements FirstInterface, SecondInterface {};
// -> FirstInterface@anonymous
new class {};
// -> class@anonymous
?>
上面顯示的名稱後面仍然跟著一個 NUL 位元組和一個唯一的後綴。
-
現在特性別名調適中的非絕對特性方法參考必須明確。
<?php
class X {
use T1, T2 {
func as otherFunc;
}
function func() {}
}
?>
如果 T1::func()
和 T2::func()
都存在,這段程式碼以前會被靜默接受,並且假設 func 指的是 T1::func
。現在它會產生一個致命錯誤,需要明確地寫出 T1::func
或 T2::func
。
-
現在會檢查特性中定義的抽象方法的簽章是否與實作類別的方法相符。
<?php
trait MyTrait {
abstract private function neededByTrait(): string;
}
class MyClass {
use MyTrait;
// 錯誤,因為回傳類型不符。
private function neededByTrait(): int { return 42; }
}
?>
-
現在已停用的函式會被視為不存在的函式。呼叫已停用的函式會回報其為未知,並且現在可以重新定義已停用的函式。
-
data://
資料流包裝器不再可寫入,這與文件記載的行為一致。
-
當其中一個運算元是陣列、資源或非多載物件時,算術和位元運算子 +
、-
、*
、/
、**
、%
、<<
、>>
、&
、|
、^
、~
、++
、--
現在會一致地拋出 TypeError。唯一的例外是陣列 +
陣列合併運算,該運算仍然支援。
-
浮點數到字串的轉換現在將始終與地區設定無關。
<?php
setlocale(LC_ALL, "de_DE");
$f = 3.14;
echo $f, "\n";
// 之前:3,14
// 現在:3.14
?>
關於自訂數字格式的方法,請參考 printf()、number_format() 和 NumberFormatter()。
-
已移除對已棄用的大括號偏移存取的支援。
<?php
// 捨棄以下寫法:
$array{0};
$array{"key"};
// 改用以下寫法:
$array[0];
$array["key"];
?>
-
現在,對私有方法套用 final 修飾詞將會產生警告,除非該方法是建構子。
-
如果物件建構子執行 exit(),則將不再呼叫物件解構子。這與建構子拋出例外時的行為一致。
-
命名空間名稱不能再包含空白:雖然 Foo\Bar
會被識別為命名空間名稱,但 Foo \ Bar
不會。相反地,保留關鍵字現在允許作為命名空間區段,這也可能會改變程式碼的解讀:new\x
現在與 constant('new\x')
相同,而不是 new \x()
。
-
巢狀三元運算子現在需要明確的括號。
-
debug_backtrace() 和 Exception::getTrace() 將不再提供對引數的參考。將無法透過回溯追蹤來更改函式引數。
-
數值字串的處理方式已更改為更直觀且更不容易出錯。為了與前導空白的處理方式保持一致,現在數值字串中允許尾端空白。這主要影響:
「前導數值字串」的概念大部分已被捨棄;保留此概念的情況是為了簡化遷移。發出 E_NOTICE
「遇到格式不正確的數值」的字串現在將發出 E_WARNING
「遇到非數值」,並且所有發出 E_WARNING
「遇到非數值」的字串現在將拋出 TypeError。這主要影響:
此 E_WARNING
到 TypeError 的更改也影響了非法字串偏移的 E_WARNING
「非法字串偏移 'string'」。從字串到 int/float 的顯式轉換行為尚未更改。
-
現在,如果魔術方法有宣告參數和返回類型,則會進行類型檢查。簽名應符合以下列表:
__call(string $name, array $arguments): mixed
__callStatic(string $name, array $arguments): mixed
__clone(): void
__debugInfo(): ?array
__get(string $name): mixed
__invoke(mixed $arguments): mixed
__isset(string $name): bool
__serialize(): array
__set(string $name, mixed $value): void
__set_state(array $properties): object
__sleep(): array
__unserialize(array $data): void
__unset(string $name): void
__wakeup(): void
-
call_user_func_array() 陣列鍵現在將被解釋為參數名稱,而不是被靜默忽略。
-
在命名空間內宣告名為 assert()
的函式將不再被允許,並會發出 E_COMPILE_ERROR
錯誤。 assert() 函式會受到引擎的特殊處理,這可能導致在定義同名命名空間函式時出現不一致的行為。