ECShop 2.x/3.x 早期基於 PHP 5.2+ 開發,大量使用已移除的 mysql_* 函數、create_function()、each() 等棄用特性,直接在 PHP 7/8 執行會大量報錯。本文系統整理核心修改清單,以 includes/cls_mysql.php 資料庫驅動重構為核心,涵蓋全站相容性修復。
檔案:includes/cls_mysql.php
關鍵點:
new mysqli(),支援持久連線 p: 前綴。mysql_query → $this->link_id->query(),回傳 mysqli_result。mysql_fetch_array → $result->fetch_array(MYSQLI_ASSOC) + $result->free()。mysql_num_rows → $result->num_rows。mysql_insert_id → $this->link_id->insert_id。mysql_error/errno → $this->link_id->error/errno。mysql_real_escape_string → $this->link_id->real_escape_string()。ping() 自動重連機制(長連線防斷)。file_put_contents。| 舊寫法 (PHP 5.x) | 新寫法 (PHP 7/8) | 影響檔案範例 |
|---|---|---|
create_function() | 匿名函數 fn() => 或 function() {} | lib_base.php, cls_template.php |
each() | foreach ($arr as $k => $v) | 全站模板解析、陣列遍歷 |
split() | explode() 或 preg_split() | cls_template.php |
ereg/eregi | preg_match/preg_match_all (加分隔符) | 驗證類、模板編譯 |
$HTTP_RAW_POST_DATA | file_get_contents('php://input') | API 入口、支付回調 |
set_magic_quotes_runtime() | 移除(PHP 5.4+ 已移除) | init.php |
call_user_method() | call_user_func([$obj, 'method']) | 插件機制 |
// includes/init.php 或入口檔案 error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE); // PHP 8.1+ 建議 error_reporting(E_ALL & ~E_DEPRECATED);
cls_template.php 修復fetch_str() 中的 preg_replace('/\{foreach\s+(.+?)\}(.+?)\{\/foreach\}/s', ...) 需將 /e 修飾符移除,改用 preg_replace_callback()。make_var() 變數解析邏輯需處理 PHP 7+ count(null) 警告,加入 is_array() 判斷。// includes/cls_session.php
// PHP 7.1+ session_start() 支援選項陣列
session_start(['read_and_close' => false, 'lazy_write' => true]);
// 連線後強制設定字符集
$this->link_id->set_charset('utf8mb4'); // 支援 emoji
$this->link_id->query("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci");
class cls_mysql {
var $link_id = null;
var $settings = [];
var $queryCount = 0;
var $queryLog = [];
// ... 其他屬性保留
function __construct($dbhost, $dbuser, $dbpw, $dbname = '', $charset = 'utf8mb4', $pconnect = 0, $quiet = 0) {
if ($quiet) $this->connect($dbhost, $dbuser, $dbpw, $dbname, $charset, $pconnect, $quiet);
else $this->settings = compact('dbhost','dbuser','dbpw','dbname','charset','pconnect');
}
function connect($dbhost, $dbuser, $dbpw, $dbname = '', $charset = 'utf8mb4', $pconnect = 0, $quiet = 0) {
$host = $pconnect ? 'p:' . $dbhost : $dbhost;
$this->link_id = new mysqli($host, $dbuser, $dbpw, $dbname, 3306);
if ($this->link_id->connect_error) {
if (!$quiet) $this->ErrorMsg("Can't connect MySQL: " . $this->link_id->connect_error);
return false;
}
$this->link_id->set_charset($charset);
$this->link_id->query("SET sql_mode=''");
if ($dbname && !$this->link_id->select_db($dbname)) {
if (!$quiet) $this->ErrorMsg("Can't select DB: $dbname");
return false;
}
return true;
}
function query($sql, $type = '') {
if ($this->link_id === null) $this->connect(...array_values($this->settings));
if ($this->queryCount++ < 99) $this->queryLog[] = $sql;
if ($this->queryTime === '') $this->queryTime = microtime(true);
if (time() > $this->starttime + 1) $this->link_id->ping();
if (!($result = $this->link_id->query($sql)) && $type != 'SILENT') {
$this->error_message[] = ['message'=>'MySQL Query Error','sql'=>$sql,'error'=>$this->link_id->error,'errno'=>$this->link_id->errno];
$this->ErrorMsg();
return false;
}
return $result;
}
function fetch_array($result, $type = MYSQLI_ASSOC) {
$row = $result->fetch_array($type);
$result->free();
return $row;
}
// ... 其他方法同理改寫
}
temp/caches/ 可寫入、自動更新。utf8mb4,Emoji 評論、商品名正常存取。Deprecated、Fatal error 記錄。mysqldump --single-transaction --routines --triggers。完成上述修改後,ECShop 可在 PHP 7.4~8.2 穩定運行,為老專案延續壽命爭取重構時間窗口。