PHP 版本演進帶來大量函數棄用與移除,從 PHP 5.3 引入 E_DEPRECATED 級別開始,到 PHP 7.0 移除 mysql_*、PHP 8.0 移除 create_function 等,每次大版本升級都伴隨代碼適配工作。本文系統梳理各版本棄用/移除函數,提供標準替代方案與遷移策略。
PHP 5.3:棄用時代的開始
PHP 5.3 引入 E_DEPRECATED 錯誤級別,標誌著大規模函數棄用的開始。
正則函數家族:ereg → preg
| 棄用函數 | 替代方案 | 說明 |
ereg() | preg_match() | 需添加定界符,如 '/pattern/' |
ereg_replace() | preg_replace() | 同樣需定界符 |
eregi() | preg_match('/pattern/i') | 使用 i 修飾符實現不區分大小寫 |
eregi_replace() | preg_replace('/pattern/i', ...) | |
split() | preg_split() | 或 explode()(固定分隔符) |
spliti() | preg_split('/pattern/i') | |
sql_regcase() | 無直接替代 | 手動構建不區分大小寫模式 |
回調函數:call_user_method → call_user_func
| 棄用函數 | 替代方案 |
call_user_method() | call_user_func([$obj, 'method']) |
call_user_method_array() | call_user_func_array([$obj, 'method'], $args) |
Session 註冊機制:session_register → $_SESSION
| 棄用函數 | 替代方案 |
session_register() | $_SESSION['key'] = $value |
session_unregister() | unset($_SESSION['key']) |
session_is_registered() | isset($_SESSION['key']) |
其他重要棄用
| 棄用函數 | 替代方案 | 備註 |
define_syslog_variables() | 直接使用常量 | 如 LOG_USER |
dl() | php.ini 中配置 extension | 運行時加載擴展不安全 |
set_magic_quotes_runtime() | 無需替代 | 魔術引號已在 5.4 移除 |
set_socket_blocking() | stream_set_blocking() | |
mysql_db_query() | mysql_select_db() + mysql_query() | 建議直接遷移 PDO/MySQLi |
mysql_escape_string() | mysql_real_escape_string() | 同上 |
mysql_close() | mysql_close($link) | 必須傳入連接資源 |
PHP 5.4:移除魔術引號、Safe Mode 等
移除的功能
- Magic Quotes:
magic_quotes_gpc、magic_quotes_runtime、magic_quotes_sybase 完全移除
- Safe Mode:相關配置項、函數全部移除
- register_globals:配置項移除(5.3 已棄用)
- register_long_arrays:
$HTTP_*_VARS 長數組移除
棄用函數
| 函數 | 替代 |
mcrypt_generic_end() | mcrypt_generic_deinit() |
mysql_list_dbs() | SHOW DATABASES SQL 查詢 |
新特性(遷移動力)
- Traits 代碼復用
- 短數組語法
[]
- 內置 Web 服務器
Closure::bind()、Closure::bindTo()
Class::{expr}() 動態方法調用
PHP 5.5:移除 mysql_* 擴展(重大)
棄用 mysql 擴展
Deprecated: mysql_connect(): The mysql extension is deprecated
and will be removed in the future: use mysqli or PDO instead
強制遷移到 MySQLi 或 PDO,無緩衝期。
mcrypt 模式函數棄用
| 棄用函數 | 替代 |
mcrypt_cbc() | mcrypt_encrypt(MCRYPT_MODE_CBC, ...) |
mcrypt_cfb() | mcrypt_encrypt(MCRYPT_MODE_CFB, ...) |
mcrypt_ecb() | mcrypt_encrypt(MCRYPT_MODE_ECB, ...) |
mcrypt_ofb() | mcrypt_encrypt(MCRYPT_MODE_OFB, ...) |
注意:mcrypt 擴展在 PHP 7.2 棄用、7.3 移除,建議遷移到 openssl_encrypt 或 sodium。
新特性
- Generators (
yield)
finally 異常處理
list() 在 foreach 中使用
Class::class 常量
- 密碼哈希 API:
password_hash()、password_verify()
PHP 5.6:棄用靜態調用非靜態方法
E_DEPRECATED:非靜態方法被靜態調用
$HTTP_RAW_POST_DATA 棄用,使用 php://input
- 編碼相關:
iconv.internal_encoding 等配置棄用,使用 default_charset
PHP 7.0:大清洗 - 移除所有棄用多年的功能
完全移除
| 移除項 | 替代方案 |
| mysql_* 全系列函數 | PDO / MySQLi |
| ereg_* 正則函數 | preg_* 系列 |
| mcrypt 別名函數 | 標準 mcrypt_* 或 openssl |
| split()、spliti()、sql_regcase() | preg_split()、explode() |
| set_magic_quotes_runtime() | 無 |
| call_user_method() 系列 | call_user_func() 系列 |
| session_register() 系列 | $_SESSION 超全局 |
| dl() | php.ini extension |
ASP 標簽 <%、<%= | <?php、<?= |
| 多個錯誤類型常量合併 | E_DEPRECATED 併入 E_ERROR |
新特性
- 標量類型聲明、返回類型聲明
- 空合併運算符
??
- 太空船運算符
<=>
- 匿名類
- CSPRNG:
random_bytes()、random_int()
- 性能提升 2x+
PHP 7.1/7.2/7.3/7.4:持續清理
| 版本 | 棄用/移除 | 替代 |
| 7.1 | mcrypt 棄用 | openssl / sodium |
| 7.2 | create_function() 棄用 | 匿名函數 fn() => |
| 7.2 | each() 棄用 | foreach / array_keys() |
| 7.2 | read_exif_data() 重命名 | exif_read_data() |
| 7.3 | mcrypt 移除 | openssl / sodium |
| 7.3 | image2wbmp() 棄用 | imagewbmp() |
| 7.4 | array_key_exists() 對象檢查棄用 | isset() / property_exists() |
| 7.4 | real 類型別名棄用 | float |
| 7.4 | 花括號數組/字符串訪問 {} 棄用 | 方括號 [] |
PHP 8.0/8.1/8.2/8.3:現代化重構
| 版本 | 關鍵移除/棄用 | 影響 |
| 8.0 | create_function() 移除 | 必須用箭頭函數 |
| 8.0 | each() 移除 | 重寫循環邏輯 |
| 8.0 | get_magic_quotes_gpc() 移除 | 直接返回 false |
| 8.0 | assert() 不再評估字符串 | 安全性提升 |
| 8.0 | 資源類型遷移為對象 | curl、gd、openssl 等返回對象 |
| 8.1 | json_encode/decode 拋出 JsonException | 需 try-catch |
| 8.1 | htmlspecialchars 默認雙重編碼 | 行為統一 |
| 8.1 | 斐波那契數列 fibonacci() 移除 | 無 |
| 8.2 | 動態屬性棄用 | 聲明屬性或用 #[\AllowDynamicProperties] |
| 8.2 | utf8_encode/decode 棄用 | mb_convert_encoding |
| 8.3 | get_class() 無參數棄用 | 傳入對象 |
遷移策略與工具鏈
1. 靜態分析工具
# PHPStan - 靜態分析
composer require --dev phpstan/phpstan
vendor/bin/phpstan analyse src --level=5
# Psalm - 類型檢查
composer require --dev vimeo/psalm
vendor/bin/psalm --show-info=false
# PHP_CodeSniffer - 編碼標準
composer require --dev squizlabs/php_codesniffer
vendor/bin/phpcs --standard=PHPCompatibility src
2. PHPCompatibility 規則集
composer require --dev phpcompatibility/php-compatibility
vendor/bin/phpcs -p --standard=PHPCompatibility --runtime-set testVersion 8.2 src
3. Rector 自動重構(神器)
composer require --dev rector/rector
vendor/bin/rector process src --dry-run
# 具體規則集
vendor/bin/rector process src --set php82
4. 升級檢查清單
- 運行測試套件:無測試先寫核心業務測試
- 啟用 E_DEPRECATED:
error_reporting(E_ALL | E_DEPRECATED)
- 掃描棄用函數:使用
phpcs + PHPCompatibility
- 分模塊遷移:數據庫層 → 業務邏輯 → 控制器 → 視圖
- 替代 mysql_*:優先用 Rector 自動轉換為 PDO
- 處理動態屬性:PHP 8.2+ 需聲明或加屬性
- 驗證第三方庫兼容性:composer update 並檢查
版本選擇建議(2024)