2024 年 PHP 日本研討會

不相容的變更

PHP 核心

字串與數字的比較

現在,數字和非數字字串之間的非嚴格比較會將數字轉換為字串,然後比較字串。數字和數字字串之間的比較方式與以前相同。值得注意的是,這表示 0 == "not-a-number" 現在被視為 false。

比較 之前 之後
0 == "0" true true
0 == "0.0" true true
0 == "foo" true false
0 == "" true false
42 == " 42" true true
42 == "42foo" true false

其他不相容的變更

  • 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()。應使用 foreachArrayIterator

  • 已移除使用 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_NOTICEE_DEPRECATED

  • display_startup_errors 現在預設為啟用。

  • 在沒有父類別的類別中使用 parent 現在會導致致命的編譯時期錯誤。

  • `@` 運算符將不再抑制致命錯誤(E_ERRORE_CORE_ERRORE_COMPILE_ERRORE_USER_ERRORE_RECOVERABLE_ERRORE_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::funcT2::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() 將不再提供對引數的參考。將無法透過回溯追蹤來更改函式引數。

  • 數值字串的處理方式已更改為更直觀且更不容易出錯。為了與前導空白的處理方式保持一致,現在數值字串中允許尾端空白。這主要影響:

    • is_numeric() 函式
    • 字串到字串的比較
    • 類型宣告
    • 遞增和遞減運算

    「前導數值字串」的概念大部分已被捨棄;保留此概念的情況是為了簡化遷移。發出 E_NOTICE「遇到格式不正確的數值」的字串現在將發出 E_WARNING「遇到非數值」,並且所有發出 E_WARNING「遇到非數值」的字串現在將拋出 TypeError。這主要影響:

    • 算術運算
    • 位元運算

    E_WARNINGTypeError 的更改也影響了非法字串偏移的 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() 函式會受到引擎的特殊處理,這可能導致在定義同名命名空間函式時出現不一致的行為。

資源到物件的遷移

若干 資源 已遷移至 物件。使用 is_resource() 檢查返回值的程式碼應改為檢查 false

COM 和 .Net (Windows)

已移除從類型程式庫匯入不區分大小寫常數的功能。com_load_typelib() 的第二個參數不能再是 false;com.autoregister_casesensitive 不能再被停用;com.typelib_file 中不區分大小寫的標記會被忽略。

CURL

CURLOPT_POSTFIELDS 不再接受物件作為陣列。要將物件解讀為陣列,請執行明確的 (array) 轉型。這同樣適用於其他接受陣列的選項。

日期和時間

mktime()gmmktime() 現在至少需要一個參數。time() 可用於取得目前的時間戳記。

DOM

已移除 DOM 擴充功能中未實作的類別,這些類別沒有任何行為且包含測試資料。這些類別在最新版本的 DOM 標準中也已被移除。

  • DOMNameList
  • DomImplementationList
  • DOMConfiguration
  • DomError
  • DomErrorHandler
  • DOMImplementationSource
  • DOMLocator
  • DOMUserDataHandler
  • DOMTypeInfo
  • DOMStringExtend

已移除 DOM 擴充功能中未實作的方法,這些方法沒有任何行為。

  • DOMNamedNodeMap::setNamedItem()
  • DOMNamedNodeMap::removeNamedItem()
  • DOMNamedNodeMap::setNamedItemNS()
  • DOMNamedNodeMap::removeNamedItemNS()
  • DOMText::replaceWholeText()
  • DOMNode::compareDocumentPosition()
  • DOMNode::isEqualNode()
  • DOMNode::getFeature()
  • DOMNode::setUserData()
  • DOMNode::getUserData()
  • DOMDocument::renameNode()

Enchant

Exif

read_exif_data() 已移除;應改用 exif_read_data()

Filter

GD

GMP

已移除 gmp_random() 函式。應改用 gmp_random_range()gmp_random_bits()

Iconv

不再支援在發生錯誤時未正確設定 errno 的 iconv 實作。

IMAP

國際化函式

LDAP

MBString

OCI8

ODBC

OpenSSL

正規表示式 (Perl 相容)

傳遞無效的跳脫序列時,它們不再被解釋為字面量。先前,這種行為需要 X 修飾符,而現在該修飾符會被忽略。

PHP 資料物件

  • 預設的錯誤處理模式已從「靜默」更改為「例外」。詳情請參閱錯誤和錯誤處理

  • 某些 PDO 方法的簽章已更改

    • PDO::query(string $query, ?int $fetchMode = null, mixed ...$fetchModeArgs)
    • PDOStatement::setFetchMode(int $mode, mixed ...$args)

PDO ODBC

php.ini 指令 pdo_odbc.db2_instance_name 已移除。

PDO MySQL

PDO::inTransaction() 現在會回報連線的實際交易狀態,而不是 PDO 維護的近似值。如果執行了受「隱式提交」約束的查詢,PDO::inTransaction() 後續將返回 false,因為交易不再有效。

PostgreSQL

  • 已不再支援使用多個參數而非連接字串的已棄用 pg_connect() 語法。

  • 已不再支援將連線作為最後一個參數傳遞的已棄用 pg_lo_import()pg_lo_export() 簽章。連線應該作為第一個參數傳遞。

  • 對於零列的結果集,pg_fetch_all() 現在將返回一個空陣列,而不是 false

Phar

與 phar 關聯的元數據將不再自動反序列化,以修復由於物件實例化、自動載入等引起的潛在安全漏洞。

反射 (Reflection)

  • 方法簽章

    • 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)

  • ReflectionType::__toString() 方法現在將返回類型的完整除錯表示形式,並且不再被棄用。特別是,結果將包含可為 Null 類型的可為 Null 指示器。返回值的格式不穩定,可能會在不同 PHP 版本之間更改。

  • Reflection export() 方法已被移除。現在可以將 reflection 物件轉換為字串。

  • ReflectionMethod::isConstructor()ReflectionMethod::isDestructor() 現在也會針對介面的 __construct()__destruct() 方法返回 true。以前,這僅適用於類別和特性 (trait) 的方法。

  • ReflectionType::isBuiltin() 方法已移至 ReflectionNamedTypeReflectionUnionType 沒有這個方法。

Sockets (通訊端)

  • 已移除socket_addrinfo_lookup() 中已棄用的 flags 參數 AI_IDN_ALLOW_UNASSIGNEDAI_IDN_USE_STD3_ASCII_RULES

標準 PHP 函式庫 (SPL)

標準函式庫

  • assert() 將不再評估字串參數,而是將它們視為任何其他參數。應使用 assert($a == $b) 而不是 assert('$a == $b')。ini 指令 assert.quiet_eval 和常數 ASSERT_QUIET_EVAL 也已被移除,因為它們將不再有任何作用。

  • 不能再不指定結果陣列的情況下使用 parse_str()

  • 已移除 string.strip_tags 篩選器。

  • strpos()strrpos()stripos()strripos()strstr()strchr()strrchr()stristr()needle 參數現在一律會被解譯為字串。先前非字串的 needles 會被解譯為 ASCII 字碼點。可以明確呼叫 chr() 來恢復先前的行為。

  • 現在 strpos()strrpos()stripos()strripos()strstr()stristr()strrchr()needle 參數可以為空。

  • 現在 substr()substr_count()substr_compare()iconv_substr()length 參數可以是 nullnull 值的行為如同未提供 length 參數,因此將返回字串的剩餘部分,而不是空字串。

  • 現在 array_splice()length 參數可以是 nullnull 值的行為與省略該參數相同,因此會移除從 offset 到陣列結尾的所有內容。

  • vsprintf()vfprintf()vprintf()args 參數現在必須是陣列。先前接受任何類型。

  • 不再支援 password_hash()'salt' 選項。如果使用 'salt' 選項,則會產生警告,忽略提供的鹽值,並改用產生的鹽值。

  • 如果傳入空字串,quotemeta() 函式現在將返回空字串。先前返回 false

  • 以下函式已被移除:

  • FILTER_SANITIZE_MAGIC_QUOTES 已被移除。

  • 不再支援以相反順序 ($pieces, $glue) 的參數呼叫 implode()

  • parse_url() 現在將區分不存在的查詢和片段與空的查詢和片段。

    • http://example.com/foo → query = null, fragment = null
    • http://example.com/foo? → query = "", fragment = null
    • http://example.com/foo# → query = null, fragment = ""
    • http://example.com/foo?# → query = "", fragment = ""
    先前所有情況都導致 query 和 fragment 為 null

  • var_dump()debug_zval_dump() 現在將使用 serialize_precision 而不是 precision 來列印浮點數。在預設配置中,這表示這些除錯函式現在以完整的精度列印浮點數。

  • 如果 __sleep() 返回的陣列包含不存在的屬性,現在將靜默忽略這些屬性。先前,此類屬性會被序列化,如同它們的值為 null

  • 啟動時的預設語系現在一律為 "C"。預設情況下,不會從環境繼承任何語系設定。先前,LC_ALL 被設定為 "C",而 LC_CTYPE 則會從環境繼承。然而,某些函式在沒有明確呼叫 setlocale() 的情況下,不會遵循繼承的語系設定。現在,如果要更改預設的語系組成部分,則一律需要明確呼叫 setlocale()

  • crypt() 中已棄用的 DES 回退機制已被移除。如果傳遞了未知的鹽值格式給 crypt(),該函式現在將會回傳失敗,並顯示 *0,而不是回退到安全性較弱的 DES 雜湊。

  • 為 SHA256/SHA512 的 crypt() 指定超出範圍的 rounds 值現在將會回傳失敗,並顯示 *0,而不是限制到最接近的限制值。這與 glibc 的行為一致。

  • 如果陣列包含比較結果相等的元素,排序函式的結果可能會有所改變。

  • 任何接受回呼函式,且未明確指定接受參數傳址的函式,現在如果使用帶有傳址參數的回呼函式,將會發出警告。範例包括 array_filter()array_reduce()。先前大多數函式已經是這種情況,但並非所有函式都是如此。

  • file_get_contents() 等函式所使用的 HTTP 資料流包裝器,現在預設宣告為 HTTP/1.1 而不是 HTTP/1.0。這不會改變用戶端的行為,但可能會導致伺服器做出不同的回應。要保留舊的行為,請設定 'protocol_version' 資料流上下文選項,例如:

    <?php
    $ctx
    = stream_context_create(['http' => ['protocol_version' => '1.0']]);
    echo
    file_get_contents('http://example.org', false, $ctx);
    ?>

  • 不再支援在沒有明確指定鹽值的情況下呼叫 crypt()。如果您想要使用自動產生的鹽值來產生強雜湊,請改用 password_hash()

  • substr()mb_substr()iconv_substr()grapheme_substr() 現在會一致地將超出範圍的偏移量限制在字串邊界內。先前,在某些情況下會回傳 false 而不是空字串。

  • 在 Windows 上,使用 shell 的程式執行函式(proc_open()exec()popen() 等)現在一律執行 %comspec% /s /c "$commandline",其效果與執行 $commandline(不帶額外引號)相同。

Sysvsem

  • sem_get()auto_release 參數已更改為接受布林值而不是整數值。

Tidy

Tokenizer (分詞器)

XMLReader

XMLReader::open()XMLReader::XML() 現在是靜態方法。它們仍然可以作為實例方法調用,但繼承類需要將它們聲明為靜態方法,如果它們覆蓋這些方法的話。

XML-RPC

XML-RPC 擴充功能已移至 PECL,不再是 PHP 發行版的一部分。

Zip

ZipArchive::OPSYS_Z_CPM 已被移除(此名稱拼寫錯誤)。請改用 ZipArchive::OPSYS_CPM

Zlib

Windows PHP 測試包

測試執行程式已從 run-test.php 更名為 run-tests.php,以符合其在 php-src 中的名稱。

新增註釋

使用者貢獻的註釋 2 則註釋

重試、中止、失敗
2 年前
上述字串與整數比較方式的變更(例如 '' == 0 現在等於 false)會產生一些其他不良後果

$a = '';

// php 8

if ( $a < 0 ) echo 'true'; // 輸出 true
if ( $a < -1) echo 'true'; // 輸出 true
if ( $a < -100 ) echo 'true'; // 輸出 true

// php 7

if ( $a < 0 ) echo 'true'; // 無輸出
if ( $a < -1) echo 'true'; // 無輸出
if ( $a < -100 ) echo 'true'; // 無輸出

因此,在網頁表單輸入的情況下,如果您預期空值等於 0,請注意不僅要留意 == 0、!= 0 和 <= 0 的比較,還要留意所有與負整數進行 < 或 <= 的比較。
aphpguy at galaxy dot za dot net
1 年前
如果您有舊專案因為 PHP7 遷移到 8 的寬鬆比較問題而損壞

例如 if ($a == 0) 在 PHP 7 和 PHP 8 之間的行為不同
(例如 $a = "" 或 $a = "123foo" 以及上面列出的其他情況)

請在舊程式碼中將

if ($a == 0) { .. }

替換為

if (cmp_eq($a, $b)) { .. }

已針對各種情境進行測試,甚至包括陣列、布林值、檔案控制代碼、管道控制代碼、物件、純量和數字。

這樣舊程式碼的行為就會與以前相同。
那麼 PHP8.x 和舊版 PHP(最高到 7.x)對於寬鬆比較將會給出完全相同的布林值 true 或 false 輸出。

function cmp_eq($a, $b) {
// 如果 $a 和 $b 都是字串類型,則將它們作為字串比較
if (is_string($a) && is_string($b)) { return $a == $b; } // 可能不是 === 因為 php 認為 '42' 等於 '042' 為 true,但 '42' === '042' 為 false。

// 如果 $a 和 $b 都是數字字串,則將它們作為數字比較
if (is_numeric($a) && is_numeric($b)) { return $a == $b; }

// 如果 $a 是空字串且 $b 是 0,反之亦然,則返回 true
if (($a === '' && $b === 0) || ($a === 0 && $b === '')) { return true; }

// 如果 $a 是非數字字串且 $b 是 0,反之亦然,則返回 true
if ((is_string($a) && ($a !== '') && ($b === 0)) || (($a === 0) && is_string($b) && ($b !== ''))) {
return true;
}
// 特殊情況 '123abc' == 123 .. php 7 將 123abc 轉換為 123,然後 123 == 123 結果為 true。讓我們模擬這種情況。
if ((is_string($a) && ($a !== '') && (is_numeric($b)) && ((bool)$b))) {
$number = filter_var($a, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); //"-234.56xyz"
return $number == $b;
}
if (is_numeric($a) && ((bool)$a) && is_string($b) && ($b !== '')) {
$number = filter_var($b, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); //"-234.56xyz"
return $a == $number;
}

// 如果 $a 是數字且 $b 是非數字字串,則將 $a 轉換為字串並比較
if (is_numeric($a) && is_string($b)) { return strval($a) == $b; }

// 如果 $b 是數字且 $a 是非數字字串,則將 $b 轉換為字串並比較
if (is_string($a) && is_numeric($b)) { return $a == strval($b); }

// 如果 $a 和 $b 都是非數字字串,則直接比較它們,如果它們相同,我們應該返回 true
return $a == $b;
} // end func cmp_eq

注意事項:更好的方法是將程式碼移植到 PHP 8,使用嚴格的變數類型,並使用 === 和 !== 運算子。

但在某些情況下,需要快速修補大量舊程式碼時,這可能會有幫助。
To Top