PHP 5.3 引入重大變更:棄用 POSIX 正則函數、移除靜態賦值引用、關閉魔術引號運行時設置。大量舊代碼升級後報 `Deprecated` 警告甚至 Fatal Error。本文提供完整對照表、批量替換策略、兼容性封裝與遷移檢查清單。
| 舊寫法 (PHP < 5.3) | 新寫法 (PHP ≥ 5.3) | 說明 |
|---|---|---|
ereg(pattern, str) | preg_match('/pattern/', str) | POSIX 正則 → PCRE,需添加定界符 / / |
eregi(pattern, str) | preg_match('/pattern/i', str) | 不區分大小寫 → i 修飾符 |
ereg_replace(pattern, repl, str) | preg_replace('/pattern/', repl, str) | 同上 |
split(pattern, str) | preg_split('/pattern/', str) | 或用 explode() (固定分隔符) |
sql_regcase() | 無直接替代,手動構建字符類 | 已移除 |
$obj = & new Class() | $obj = new Class() | new 自動返回引用,& 多餘且棄用 |
set_magic_quotes_runtime() | 刪除調用 | PHP 5.4 完全移除,魔術引號特性廢棄 |
get_magic_quotes_gpc() | 始終返回 false | PHP 5.4+ 無需手動 stripslashes() |
call_user_method() | call_user_func() | 已移除 |
define_syslog_variables() | 無需調用,直接用 openlog() | 已移除 |
// 舊
if ( ereg('^[0-9]+$', $input ) ) { ... }
$str = ereg_replace('[^a-zA-Z0-9]', '', $str);
// 新
if ( preg_match('/^[0-9]+$/', $input ) ) { ... }
$str = preg_replace('/[^a-zA-Z0-9]/', '', $str);
// 注意:ereg 隱含 ^...$ 全匹配,preg_match 需顯式加 ^$
// ereg 區分大小寫,eregi 不區分 → preg_match 加 i 修飾符
// 舊 (報 Deprecated: Assigning the return value of new by reference is deprecated) $instance = & new Singleton(); // 新 $instance = new Singleton(); // PHP 5+ new 默認返回對象引用,無需 &
// 舊啟動文件常見代碼
set_magic_quotes_runtime(0); // 直接刪除此行
// 舊輸入過濾
if ( get_magic_quotes_gpc() ) {
$_GET = array_map('stripslashes', $_GET);
$_POST = array_map('stripslashes', $_POST);
$_COOKIE = array_map('stripslashes', $_COOKIE);
}
// PHP 5.4+ get_magic_quotes_gpc() 恒返回 false,上述代碼無效且無必要
// 現代框架 (Laravel/Symfony/Yii2) 已內建輸入處理,無需手動干預
# 安裝 composer require --dev squizlabs/php_codesniffer phpcompatibility/php-compatibility # 掃描項目 (檢測 5.3-8.2 兼容性) phpcs --standard=PHPCompatibility /path/to/project -p
composer require --dev rector/rector # 建立 rector.php 配置 vendor/bin/rector process /path/to/project --dry-run vendor/bin/rector process /path/to/project
Rector 可自動完成:ereg→preg、& new 移除、魔術引號清理、類型聲明補全等數十項重構。
# 查找所有 ereg 系列
grep -rn "ereg" --include="*.php" .
# 批量替換 (謹慎使用,建議先備份)
find . -name "*.php" -exec sed -i 's/ereg(/preg_match(/g' {} \;
find . -name "*.php" -exec sed -i 's/ereg_replace(/preg_replace(/g' {} \;
# 後續需手動補全定界符與修飾符
升級初期可抑制 `E_DEPRECATED` 讓舊代碼暫時運行,但**必須盡快修復**:
// php.ini error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT // 或代碼中 error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
| 檢查項 | 驗證方法 | 風險等級 |
|---|---|---|
| 所有 ereg/eregi/ereg_replace/split 調用 | grep 掃描 + 單元測試 | 高 (Fatal Error) |
| & new 靜態賦值 | grep "& new" + 運行測試 | 中 (Deprecated) |
| set_magic_quotes_runtime/get_magic_quotes_gpc | grep 掃描 | 中 (函數不存在) |
| 舊式類定義 (var $prop) | grep "var $" → 改 public/protected/private | 低 (Deprecated) |
| __autoload() 函數 | 改用 spl_autoload_register() | 中 (棄用) |
| mysql_* 函數 | 遷移至 PDO/mysqli | 高 (PHP 7 移除) |
| create_function() | 改用匿名函數 fn() / function() | 中 (PHP 7.2 棄用) |
| each() 函數 | 改用 foreach | 中 (PHP 7.2 棄用) |
declare(strict_types=1); 所有文件頂部。系統化遷移而非打補丁,能徹底消除兼容性隱患,享受現代 PHP 的性能與語法紅利。