You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP7迁移至PHP8问题:购物车对象构造函数未调用

问题描述

要将线上运营的电商网站从PHP 7.x版本迁移至PHP 8.x版本,本地使用XAMPP 7.4.3和8.1.6分别测试。PHP 8环境下网站主功能看似正常,但basket对象无法正常初始化——PHP 7中可以正常输出$cartid变量,PHP 8中无法输出该变量。

相关代码片段

basket.php

...

include ("sqlcart.php");

$cart = new basket;
...

sqlcart.php

class basket
{
    var $items;
    var $empty;
    var $cartid;
    var $voucher_id_set;

    function basket()
    {
        global $cartid;
        global $vat_rate;
        global $voucher_id_set;
        global $outmail;
        global $conn;
        global $_COOKIE;
        global $_POST;

        $voucher_id_set = 0;

        $number = 0;

        if (isset($_COOKIE["cart_id"])) {
            $cartid = ClearString(substr($_COOKIE["cart_id"], 0, 10));

            $testcartid = $cartid;
            settype($testcartid, "integer");

            if ($testcartid > 0) {
                $strsql = "SELECT * from g_tempbasket where basket_id = '" . clearstring(substr($cartid, 0, 10)) . "'";
                $result = safedb_query($strsql);
                $number = mysqli_num_rows($result);
            } else {
                $number = 0;
            }
        } else {
            // force cart creation
            $number = 0;
        }


        if ($number == 0) {

            $todaydate = date("Y-m-d h:i:s");
            $strsql = "INSERT INTO g_tempbasket (basket_id,date) ";
            $strsql .= "VALUES (NULL,'$todaydate')";

            safedb_query($strsql);

            $newcartid = mysqli_insert_id($conn);

            if ($outmail == 1) {
                setcookie("cart_id", $newcartid, time() + (24 * 3600), "", ".website.co.uk", 1);
                setcookie("voucher_id", "", 0, "", ".website.co.uk", 1);
            } else {
                setcookie("cart_id", $newcartid, time() + (24 * 3600));
                setcookie("voucher_id", "", 0);
            }
            $cartid = $newcartid;

        }

        $strsql = "SELECT t.product_id, p.descript, p.cost, t.qty ";
        $strsql .= "FROM g_tempbasket AS tb, g_product AS p, g_tempitems AS t ";
        $strsql .= "WHERE tb.basket_id = t.basket_id ";
        $strsql .= "AND t.product_id = p.product_id ";
        $strsql .= "AND tb.basket_id = " . $cartid;

        $result = safedb_query($strsql);
        $number = mysqli_num_rows($result);

        mysqli_free_result($result);

        //$this->items=$result;

        if ($number != 0) {
            $this->empty = false;
        } else {
            $this->empty = true;
        }
    } //function 

    function additem($id, $name, $addcount)
    {
        global $cartid;

        // Get product info to add
        $strsql = "SELECT descript, cost, no_vat FROM g_product ";
        $strsql .= "WHERE product_id = '" . $id . "'";
        $prodaddresult = safedb_query($strsql);
        $prodaddrow = mysqli_fetch_assoc($prodaddresult);
        $prodname = $prodaddrow["descript"];
        $prodcost = $prodaddrow["cost"];
        $prodnovat = $prodaddrow["no_vat"];
        
        $strsql = "SELECT qty FROM g_tempitems ";
        $strsql .= "WHERE basket_id = " . $cartid;
        $strsql .= " AND product_id = '" . $id . "'";

        $result = safedb_query($strsql);
        $number = mysqli_num_rows($result);

        $strsqls = "SELECT prod_code FROM g_ship_options ";
        $strsqls .= "WHERE prod_code =  '" . $id . "'";
        $sresult = safedb_query($strsqls);
        $snumber = mysqli_num_rows($sresult);

        if ($number == 0) {
            if ($id == "" || $addcount < 1) { // Basic anti-bot validation
                header("Location: index.php");
                exit;
            }
        if ($snumber != 0) { // Item is shipping - mark in basket
            $strsql = "INSERT INTO g_tempitems ";
            $strsql .= "(basket_id, product_id, qty, shipping, descript, cost, no_vat) ";
            $strsql .= "VALUES (" . $cartid . ", '" . $id . "', " . $addcount . ", 1, '" . $prodname . "', '" . $prodcost . "', '" . $prodnovat . "')";
          } else { // Non-shipping item
              $strsql = "INSERT INTO g_tempitems ";
            $strsql .= "(basket_id, product_id, qty, shipping, descript, cost, no_vat) ";
              $strsql .= "VALUES (" . $cartid . ", '" . $id . "', " . $addcount . ", 0, '" . $prodname . "', '" . $prodcost . "', '" . $prodnovat . "')";
        }
        } else {
      if ($id == "") { // Basic anti-bot validation
                header("Location: index.php");
                exit;
            }
        $currow = mysqli_fetch_assoc($result);
            $current = $currow["qty"];
        $new = $current + $addcount;
        if ($new <= 0) {
            $new = 1;
            }

            $strsql = "UPDATE g_tempitems ";
            $strsql .= "SET qty = " . $new . ", ";
            $strsql .= "descript = '" . $prodname . "', ";
            $strsql .= "cost = " . $prodcost . ", ";
            $strsql .= "no_vat = " . $prodnovat . " ";
            $strsql .= "WHERE basket_id = " . $cartid . " ";
            $strsql .= "AND product_id = '" . $id . "'";
        }
        mysqli_free_result($result);
        safedb_query($strsql);

        $this->empty = false;
    }

}
原因与解决方法

问题核心是PHP 8.x彻底废弃了旧式构造函数(即与类同名的函数作为构造函数)。PHP 7.x中该写法已标记为过时但仍可运行,到PHP 8.x中,它会被当作普通方法,不会在实例化对象时自动执行。

你的basket类里的function basket()就是旧式构造函数,PHP 8下实例化new basket时不会调用这个方法,导致里面的$cartid初始化逻辑完全未执行,自然无法输出变量值。

修复方法:将旧式构造函数改为PHP标准的__construct()方法,原有逻辑保持不变:

class basket
{
    var $items;
    var $empty;
    var $cartid;
    var $voucher_id_set;

    // 替换原有的function basket()
    function __construct()
    {
        global $cartid;
        global $vat_rate;
        global $voucher_id_set;
        global $outmail;
        global $conn;
        global $_COOKIE;
        global $_POST;

        // 原有的初始化逻辑全部保留
        $voucher_id_set = 0;
        $number = 0;
        // ... 后续代码不变
    }

    // 其他方法保持不变
}

额外注意事项:

  • 代码中同时出现ClearString和clearstring,PHP对函数名大小写不敏感,但统一写法更规范
  • 当前SQL语句使用字符串拼接构建,存在注入风险,建议尽快改用预处理语句

内容的提问来源于stack exchange,提问作者Mike West

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 19:18:19