PHP Conference Japan 2024

向下不相容的變更

PHP 核心

$GLOBALS 存取限制

現在對 $GLOBALS 陣列的存取有一些限制。 讀取和寫入個別陣列元素,例如 $GLOBALS['var'] 繼續照常運作。 也繼續支援對整個 $GLOBALS 陣列的唯讀存取。 但是,不再支援對整個 $GLOBALS 陣列的寫入存取。 例如,array_pop($GLOBALS) 將會導致錯誤。

在繼承方法中使用 static 變數

當使用靜態變數的方法被繼承(但未被覆寫)時,繼承的方法現在將與父方法共享靜態變數。

<?php
class A {
public static function
counter() {
static
$counter = 0;
$counter++;
return
$counter;
}
}
class
B extends A {}
var_dump(A::counter()); // int(1)
var_dump(A::counter()); // int(2)
var_dump(B::counter()); // int(3),先前為 int(1)
var_dump(B::counter()); // int(4),先前為 int(2)
?>
這意味著方法中的靜態變數現在的行為與靜態屬性相同。

在必要參數之前指定的選用參數

在必要參數之前指定的選用參數現在一律被視為必要參數,即使使用具名參數呼叫也是如此。從 PHP 8.0.0 開始,但在 PHP 8.1.0 之前,以下程式碼在定義時會發出棄用通知,但在呼叫時仍可成功執行。從 PHP 8.1.0 開始,會拋出 ArgumentCountError 類別的錯誤,就像使用位置參數呼叫一樣。

<?php
function makeyogurt($container = "bowl", $flavour)
{
return
"Making a $container of $flavour yogurt.\n";
}
try
{
echo
makeyogurt(flavour: "raspberry");
}
catch (
Error $e)
{
echo
get_class($e), ' - ', $e->getMessage(), "\n";
}
?>

以上範例在 PHP 8.0 中的輸出

Deprecated: Required parameter $flavour follows optional parameter $container
 in example.php on line 3
Making a bowl of raspberry yogurt.

以上範例在 PHP 8.1 中的輸出

Deprecated: Optional parameter $container declared before required parameter
 $flavour is implicitly treated as a required parameter in example.php on line 3
ArgumentCountError - makeyogurt(): Argument #1 ($container) not passed

請注意,可以在必要參數之前使用預設值 **null** 來指定可為 Null 的類型,但該參數仍然是必要的。

與內建類別的返回類型相容性

現在,大多數非 final 的內部方法都要求覆寫方法宣告兼容的返回類型,否則在繼承驗證期間會發出棄用通知。如果由於 PHP 跨版本兼容性問題而無法為覆寫方法宣告返回類型,則可以添加 ReturnTypeWillChange 屬性來抑制棄用通知。

新的關鍵字

readonly 現在是一個關鍵字。但是,它仍然可以用作函數名稱。

never 現在是一個保留字,因此它不能用於命名類別、介面或 trait,並且也禁止在命名空間中使用。

資源到物件的遷移

幾個 資源 已遷移到 物件。使用 is_resource() 進行的返回值檢查應該替換為檢查 false

MySQLi

mysqli_fetch_fields()mysqli_fetch_field_direct() 現在對於 max_length 將一律返回 0。此資訊可以透過迭代結果集並取得最大長度來計算。這也是 PHP 之前內部執行的操作。

MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH 選項已不再有任何作用。

MYSQLI_STORE_RESULT_COPY_DATA 選項已不再有任何作用。將任何值傳遞給 mysqli::store_result()mode 參數將不再有任何作用。

mysqli::connect() 現在於成功時返回 true 而不是 null

預設的錯誤處理模式已從「靜默」更改為「例外」。請參閱 MySQLi 回報模式 頁面,以瞭解更多相關細節以及如何明確設定此屬性。要恢復先前的行為,請使用:mysqli_report(MYSQLI_REPORT_OFF);

繼承 mysqli_stmt::execute() 的類別現在需要指定額外的可選參數。

MySQLnd

mysqlnd.fetch_data_copy INI 指令已被移除。這不應導致使用者可見的行為變化。

OpenSSL

EC 私鑰現在將以 PKCS#8 格式而不是傳統格式匯出,就像所有其他金鑰一樣。

openssl_pkcs7_encrypt()openssl_cms_encrypt() 現在預設使用 AES-128-CBC 而不是 RC2-40。RC2-40 密碼被認為是不安全的,OpenSSL 3 預設不啟用它。

PHP 資料物件 (PDO)

PDO::ATTR_STRINGIFY_FETCHES 現在將 bool 類型的值轉換為字串 "0""1"。先前 bool 值不會被轉換為字串。

在未啟用 PDO::ATTR_STRINGIFY_FETCHES 的情況下,使用 PDO::PARAM_LOB 呼叫 PDOStatement::bindColumn() 現在將始終綁定串流結果。先前,結果可能是串流或字串,取決於使用的資料庫驅動程式和執行綁定的時間。

MySQL 驅動程式

使用模擬的預備語句時,結果集中的整數和浮點數現在將使用原生 PHP 類型返回,而不是 string 類型。這與原生預備語句的行為一致。可以透過啟用 PDO::ATTR_STRINGIFY_FETCHES 選項來恢復先前的行為。

SQLite 驅動程式

結果集中的整數和浮點數現在將使用原生 PHP 類型返回。可以透過啟用 PDO::ATTR_STRINGIFY_FETCHES 選項來恢復先前的行為。

Phar

為了符合 ArrayAccess 介面,Phar::offsetUnset()PharData::offsetUnset() 不再返回 bool 值。

標準

version_compare() 不再接受未記載的運算子縮寫。

htmlspecialchars()htmlentities()htmlspecialchars_decode()html_entity_decode() 以及 get_html_translation_table() 現在預設使用 ENT_QUOTES | ENT_SUBSTITUTE,而不是 ENT_COMPAT。這表示 ' 會被轉義為 &#039;,而之前則不會有任何動作。此外,格式錯誤的 UTF-8 將會被 Unicode 替代字元取代,而不是產生空字串。

debug_zval_dump() 現在會印出參考包裝器的引用計數,而不是只在值前面加上 &。這更準確地模擬了自 PHP 7.0 以來的參考表示方式。

debug_zval_dump() 現在會針對內部字串和不可變陣列印出 interned,而不是虛擬的引用計數。

標準 PHP 函式庫 (SPL)

SplFixedArray 現在會像 陣列 一樣進行 JSON 編碼。

新增註釋

使用者貢獻的註釋

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