PHP Conference Japan 2024

不相容的變更

雖然在本節中沒有明確說明,但每個新的函式類別、介面、列舉常數都可能導致拋出重定義錯誤

PHP 核心

exit() 行為變更

exit()(以及 die())語言結構現在的行為更像函式。這表示它們現在可以像可呼叫物件一樣被傳遞,會受到 strict_types 宣告陳述式的影響,並且現在會執行一般的類型強制轉換,而不是將任何非整數值轉換為字串。

因此,將無效類型傳遞給 exit()die() 現在會一致地導致拋出 TypeError

比較期間的遞迴

在比較期間遇到遞迴現在會導致 錯誤 (Error) 例外,而不是 E_ERROR 致命錯誤。

唯讀屬性的間接修改

__clone() 內不再允許唯讀屬性的間接修改,例如 $ref = &$this->readonly。唯讀初始化已經禁止這種做法,這是「複製期間唯讀重新初始化」實作中的疏忽。

常數的類型變更

PHP_DEBUGPHP_ZTS 常數現在是 布林值 (bool) 類型。以前它們是 整數 (int) 類型。

暫存檔名長度

上傳檔案和由 tempnam() 函式建立的檔案的名稱現在長了 13 個位元組。總長度仍然取決於平台。

移除 E_STRICT 錯誤級別

E_STRICT 錯誤級別已被移除,因為它不再在 PHP 引擎中使用。E_STRICT 常數已被棄用。

現在已類型化的擴充類別常數

以下擴充類別常數現在在其常數上宣告類型

資源到物件的遷移

幾個 資源 已遷移到 物件。使用 is_resource() 的返回值檢查應該替換為檢查 false,除非另有說明。

DBA

DBA 函式現在接受並返回 Dba\Connection 物件,而不是 dba_connection 資源

ODBC

ODBC 函式現在接受並返回 Odbc\Result 物件,而不是 odbc_result 資源

ODBC 函式現在接受並返回 Odbc\Connection 物件,而不是 odbc_connection 資源

SOAP

SoapClient::$httpurl 屬性現在是 Soap\Url 物件,而不是 soap_url 資源。使用 is_resource() 的檢查(即 is_resource($client->httpurl))應該替換為檢查 null(即 $client->httpurl !== null)。

SoapClient::$sdl 屬性現在是 Soap\Sdl 物件,而不是 soap_sdl 資源。使用 is_resource() 的檢查(即 is_resource($client->sdl))應該替換為檢查 null(即 $client->sdl !== null)。

新的警告和例外

已新增在程式設計錯誤(例如提供無效值作為參數)時觸發的新警告和例外。

Curl

curl_multi_select() 現在如果 timeout 參數小於 0 或大於 PHP_INT_MAX,則會拋出 ValueError

Gd

imagejpeg()imagewebp()imagepng()imageavif() 現在如果傳入無效的 quality 參數,則會拋出 ValueError

如果傳入無效的 speed 參數值,imageavif() 現在會拋出 ValueError

如果 widthheight 參數發生下溢/上溢,imagescale() 現在會拋出 ValueError

如果傳入無效的 mode 參數值,imagescale() 現在會拋出 ValueError

使用 IMG_FILTER_SCATTER 濾鏡時,如果 subplus 參數發生下溢/上溢,imagefilter() 現在會拋出 ValueError

Gettext

如果 domain 為空字串,bind_textdomain_codeset()textdomain()d()*gettext() 現在會拋出 ValueError

Intl

resourcebundle_get()ResourceBundle::get() 以及存取 ResourceBundle 物件上的偏移量現在會在以下情況拋出錯誤:

如果 locale 無效,IntlDateFormatter::__construct() 會拋出 ValueError

如果 locale 無效,NumberFormatter::__construct() 會拋出 ValueError

MBString

mb_encode_numericentity()mb_decode_numericentity() 現在會檢查 map 是否僅由 int 組成,如果不是,則會拋出 ValueError

現在,如果 type 無效,mb_http_input() 總是會拋出 ValueError

mb_http_output() 現在會檢查 encoding 是否包含任何空位元組,如果包含,則會拋出 ValueError

ODBC

row 小於或等於 0 時,odbc_fetch_row() 會傳回 false。在這種情況下,現在會發出警告。

PCNTL

pcntl_sigprocmask()pcntl_sigwaitinfo()pcntl_sigtimedwait() 函式現在會拋出

如果 mode 不是 SIG_BLOCKSIG_UNBLOCKSIG_SETMASK 其中之一,pcntl_sigprocmask() 函式現在會拋出 ValueError

pcntl_sigtimedwait() 函式現在會拋出

  • 如果 seconds 小於 0,則拋出 ValueError
  • 如果 nanoseconds 小於 0 或大於 1e9,則拋出 ValueError
  • 如果 secondsnanoseconds 皆為 0,則拋出 ValueError

SimpleXML

使用非 XML 物件呼叫 simplexml_import_dom() 現在會拋出 TypeError,而不是 ValueError

標準

round() 函式現在會驗證 mode 的值,並在模式無效時拋出 ValueError。以前,無效的模式會被解釋為 PHP_ROUND_HALF_UP

str_getcsv() 現在會在 separatorenclosure 參數不是單一位元組長,或者 escape 參數不是單一位元組長也不是空字串時,拋出 ValueError 異常。這讓行為與 fputcsv()fgetcsv() 的行為一致。

mode 參數無效時,php_uname() 函式現在會拋出 ValueError 異常。

unserialize()"allowed_classes" 選項,如果它不是一個類別名稱的 陣列,現在會拋出 TypeErrorValueError 異常。

XMLReader

將無效的字元編碼傳遞給 XMLReader::open()XMLReader::XML() 現在會拋出 ValueError 異常。

傳遞包含空位元組的 字串 以前會發出警告,現在會拋出 ValueError 異常。

XMLWriter

傳遞包含空位元組的 字串 以前會發出警告,現在會拋出 ValueError 異常。

XSL

XSLTProcessor::setParameter() 的參數包含空位元組時,現在會拋出 ValueError 異常。這從一開始就沒有正常運作,這就是為什麼現在它會拋出異常。

使用非 XML 物件呼叫 XSLTProcessor::importStyleSheet() 現在會拋出 TypeError 異常,而不是 ValueError 異常。

在評估期間未能呼叫 PHP 函式回呼現在會拋出異常,而不是發出警告。

DOM

某些 DOM 方法以前如果無法配置新的節點,則會返回 false 或代碼為 DOM_PHP_ERRDOMException。它們現在會一致地拋出代碼為 DOM_INVALID_STATE_ERRDOMException。這種情況極不可能發生,受影響的機率很低。因此,DOMImplementation::createDocument() 現在的暫定返回類型為 DOMDocument,而不是 DOMDocument|false

以前,DOMXPath 物件可以被複製,但會產生無法使用的物件。現在已不再可能,複製 DOMXPath 物件現在會拋出 Error 異常。

DOMImplementation::getFeature() 方法已被移除。

GMP

GMP 類別現在是 final 的,不能再被繼承。

MBString

在無效字串(包含編碼錯誤的字串)上,mb_substr() 現在以與大多數其他 mbstring 函式相同的方式解釋字元索引。這表示 mb_strpos() 返回的字元索引可以傳遞給 mb_substr()

對於 SJIS-Mac (MacJapanese) 字串,傳遞給 mb_substr() 的字元索引現在指的是將字串轉換為 Unicode 時產生的 Unicode 字碼點的索引。這一點很重要,因為大約有 40 個 SJIS-Mac 字元會轉換為多個 Unicode 字碼點的序列。

MySQLi

已移除未使用的且未記載的常數 MYSQLI_SET_CHARSET_DIR

已移除 MYSQLI_STMT_ATTR_PREFETCH_ROWS 常數。此功能在 mysqlnd 中無法使用。

已移除 MYSQLI_CURSOR_TYPE_FOR_UPDATEMYSQLI_CURSOR_TYPE_SCROLLABLE 常數。此功能從未被實作,無論是使用 mysqlnd 還是 libmysql。

已移除未使用的 MYSQLI_TYPE_INTERVAL 常數,它目前是一個虛設常數,並且是 MYSQLI_TYPE_ENUM 的別名。

MySQLnd

對於 MySQL 伺服器版本 8.0.24 及以上版本,回報的 MySQL 伺服器等待逾時錯誤碼已從 2006 變更為 4031

Opcache

在 64 位元架構上,opcache.interned_strings_buffer 設定的最大值現在是 32767。先前是 4095

JIT

JIT 的預設組態值已從 opcache.jit=tracingopcache.jit_buffer_size=0 分別變更為 opcache.jit=disableopcache.jit_buffer_size=64M

這不會影響預設的可觀察行為,因為 JIT 仍然預設為停用。然而,它現在是透過 opcache.jit 設定停用,而不是 opcache.jit_buffer_size。這可能會影響先前僅透過 opcache.jit_buffer_size 啟用 JIT 而未同時使用 opcache.jit 指定 JIT 模式的使用者。要啟用 JIT 編譯,請相應地設定 opcache.jit 組態值。

如果啟用了 JIT 編譯,如果 JIT 編譯器的初始化因任何原因失敗,PHP 現在將在啟動時以致命錯誤退出。

PCNTL

pcntl_sigprocmask()pcntl_sigwaitinfo()pcntl_sigtimedwait() 函式現在在失敗時一律返回 false。在某些情況下,以前它可能會返回值 -1

PCRE

內建的 pcre2lib 已更新至 10.44 版。因此,`{,3}` 現在會被識別為量詞而不是文字。此外,UCP 模式下某些字元類別的意義已更改。請參閱 » PCRE2 更新日誌 以取得完整的變更記錄。

PDO_DBLIB

Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIERPdo\Dblib::ATTR_DATETIME_CONVERT 屬性現在作為布林值屬性而不是整數屬性。因此,透過 PDO::setAttribute() 設定屬性以及透過 PDO::getAttribute() 擷取屬性時,預期和或返回 bool 值。

PDO_FIREBIRD

PDO::ATTR_AUTOCOMMIT 屬性現在作為布林值屬性而不是整數屬性。因此,透過 PDO::setAttribute() 設定屬性以及透過 PDO::getAttribute() 擷取屬性時,預期和或返回 bool 值。

此擴充功能現在公開了一些 Firebird C++ API,因此建置此擴充功能現在需要 C++ 編譯器。此外,現在必須針對 fbclient 3.0 或更高版本編譯此擴充功能。

PDO_MYSQL

PDO::ATTR_AUTOCOMMITPDO::ATTR_EMULATE_PREPARESPDO::MYSQL_ATTR_DIRECT_QUERY 屬性現在作為布林值屬性而不是整數屬性。因此,透過 PDO::setAttribute() 設定屬性以及透過 PDO::getAttribute() 擷取屬性時,預期和或返回 bool 值。

PDO_PGSQL

DSN 的憑證,設定後,會優先於 PDO 建構函式的對應項,更接近文件所述的狀態。

SimpleXML

SimpleXMLElement 不僅是 XML 元素的表示法,它也是一個 RecursiveIterator。在 PHP 8.4.0 之前,它的一些方法(例如 SimpleXMLElement::asXML()SimpleXMLElement::getName())以及將此類實例轉換為 string 會隱式地重設迭代器。

這可能會導致非預期的無限迴圈,因為迭代器會被回溯。例如

<?php

$xmlString
= "<root><a><b>1</b><b>2</b><b>3</b></a></root>";
$xml = simplexml_load_string($xmlString);

$nodes = $xml->a->b;
foreach (
$nodes as $nodeData) {
echo
"nodeData: " . $nodeData . "\n";

$xml = $nodes->asXml();
}

原本會導致無限迴圈。

nodeData: 1
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
// ...

然而,這個行為現在已被修正,SimpleXMLElement 不會再隱式地重置迭代器資料,除非明確地回繞。這意味著先前的範例現在會產生

nodeData: 1
nodeData: 2
nodeData: 3

SOAP

SoapClient::$typemap 現在是一個 陣列 而不是 資源。使用 is_resource() 的檢查(例如 is_resource($client->typemap))應該替換為檢查 null(例如 $client->typemap !== null)。

SOAP 擴充功能現在選擇性地依賴於 session 擴充功能。如果 PHP 在沒有 session 擴充功能的情況下建置,並且啟用了 --enable-rtld-now 設定標誌,如果也使用了 SOAP 擴充功能,現在會發生啟動錯誤。要解決此問題,請不要使用 rtld-now 或載入 session 擴充功能。

標準

當使用 strcspn()characters 為空字串時,現在會返回字串的長度,而不是錯誤地在第一個空位元組處停止。

http_build_query() 現在可以正確處理支援的列舉類型 (backed enums)。

stream_bucket_make_writeable()stream_bucket_new() 現在會返回 StreamBucket 實例,而不是 stdClass 的實例。

Tidy (整潔程式庫)

建構函式中的失敗現在會拋出例外,而不是發出警告並產生損壞的物件。

XML

xml_set_()*_handler() 函式現在會宣告並檢查 `handler` 參數是否為有效的 callable|string|null 簽章。此外,對於以 xml_set_object() 設定之物件的方法名稱對應的 string 類型值,現在會檢查該方法是否存在於先前傳遞物件的類別中。這表示現在必須在將方法名稱設定為 callable 之前呼叫 xml_set_object()。傳遞空字串以停用處理程式仍然允許,但不建議使用。

然而,由於 xml_set_object() 和傳遞非 callable 的字串已被棄用。建議使用直接參考該方法的 callable 來更改此類實例。

新增註記

使用者貢獻的註記

此頁面沒有使用者貢獻的註記。
To Top