首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

ECShop 升級相容 PHP 7/8 完整修改指南:資料庫層重構、棄用函數替換、錯誤修復

     編輯:PHP 綜合知識

ECShop 2.x/3.x 早期基於 PHP 5.2+ 開發,大量使用已移除的 mysql_* 函數、create_function()、each() 等棄用特性,直接在 PHP 7/8 執行會大量報錯。本文系統整理核心修改清單,以 includes/cls_mysql.php 資料庫驅動重構為核心,涵蓋全站相容性修復。

核心修改清單

1. 資料庫驅動全面改用 mysqli(PDO 亦可)

檔案: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。

2. 棄用函數替換對照表

舊寫法 (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/eregipreg_match/preg_match_all (加分隔符)驗證類、模板編譯
$HTTP_RAW_POST_DATAfile_get_contents('php://input')API 入口、支付回調
set_magic_quotes_runtime()移除(PHP 5.4+ 已移除)init.php
call_user_method()call_user_func([$obj, 'method'])插件機制

3. 錯誤回報層級調整

// includes/init.php 或入口檔案
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE);
// PHP 8.1+ 建議
error_reporting(E_ALL & ~E_DEPRECATED);

4. 模板引擎 cls_template.php 修復

  • fetch_str() 中的 preg_replace('/\{foreach\s+(.+?)\}(.+?)\{\/foreach\}/s', ...) 需將 /e 修飾符移除,改用 preg_replace_callback()。
  • make_var() 變數解析邏輯需處理 PHP 7+ count(null) 警告,加入 is_array() 判斷。

5. Session/資料庫編碼

// 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");

cls_mysql.php 關鍵片段(mysqli 版)

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;
    }
    // ... 其他方法同理改寫
}

驗證清單(升級後必測)

  1. 前台首頁、分類頁、商品詳情頁正常顯示。
  2. 後台登入、商品管理、訂單處理、報表匯出無錯誤。
  3. 支付回調(支付寶、微信)正確寫入訂單狀態。
  4. 模板編譯緩存目錄 temp/caches/ 可寫入、自動更新。
  5. 資料庫編碼 utf8mb4,Emoji 評論、商品名正常存取。
  6. PHP 錯誤日誌無 Deprecated、Fatal error 記錄。

遷移建議

  • **分階段進行**:先建立測試環境跑自動化測試(PHPUnit/Codeception),再灰度釋出。
  • **資料庫備份**:升級前完整備份 mysqldump --single-transaction --routines --triggers。
  • **考慮重構**:ECShop 架構老舊,若為長期專案,建議漸進式重寫為 Laravel/ThinkPHP 現代框架,而非持續修補。

完成上述修改後,ECShop 可在 PHP 7.4~8.2 穩定運行,為老專案延續壽命爭取重構時間窗口。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved