0

We need to migrate our live online store from PHP 7.x to PHP 8.x

My main XAMPP folder is running PHP 7.4.3, and I've installed the latest XAMPP (8.1.6) into another folder.

The main site seems to work fine when I run the PHP 8 instance, but the basket object doesn't seem to be starting.

I can tell as I can echo out $cartid from PHP 7 but not 8.

Have I missed a config option I need to edit, or has something changed in the way PHP 8.x handles global variables or objects?

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;
    }

Dharman
  • 30,962
  • 25
  • 85
  • 135
Mike West
  • 15
  • 5
  • What does your http server's error log file say what the issue is? – arkascha Jul 24 '22 at 07:44
  • 1
    Your basket class [throws a warning at me](https://phpize.online/sql/mysql57/undefined/php/php7/109fa2cec0e5e10e104ccdb3cd7bd3fc/) at 7.4. Do you ever pay the heed to the error messages? – Your Common Sense Jul 24 '22 at 07:47
  • 1
    On a side note, whatever safedb_query() function is a cargo cult code that is anything but safe. And so clearstring() is – Your Common Sense Jul 24 '22 at 07:49
  • @YourCommonSense - Thanks - I'd looked at the docs but not understood that. function basket() changed to function __construct() and it sprang into life The server hadn't been showing the error - more config digging required I think! – Mike West Jul 24 '22 at 08:03
  • Define the scope of your methods and variables. Public, private or protected. Stop using global and learn the difference between $this-> and self:: variable access – MisterG13 Jul 24 '22 at 08:59
  • **Warning:** You are wide open to [SQL Injections](https://php.net/manual/en/security.database.sql-injection.php) and should use parameterized **prepared statements** instead of manually building your queries. They are provided by [PDO](https://php.net/manual/pdo.prepared-statements.php) or by [MySQLi](https://php.net/manual/mysqli.quickstart.prepared-statements.php). Never trust any kind of input! Even when your queries are executed only by trusted users, [you are still in risk of corrupting your data](http://bobby-tables.com/). [Escaping is not enough!](https://stackoverflow.com/q/32391315) – Dharman Jul 24 '22 at 16:37
  • @Dharman Thanks for the feedback and the edits. I'd question the edit of the title though. I asked the question as I didn't know anything about object constructors. With the title as it is now I would not have known to look at this question (or the other questions it has been linked to) – Mike West Jul 25 '22 at 16:57
  • Ok, but the word you used "starting" isn't very technical. I assume it means that the constructor is not called, but I don't actually know what you meant by "starting". – Dharman Jul 25 '22 at 16:59

1 Answers1

3

Propably incompatible changes. From docs:

Methods with the same name as the class are no longer interpreted as constructors. The __construct() method should be used instead.

Source: https://www.php.net/manual/en/migration80.incompatible.php

Robert
  • 372
  • 1
  • 4
  • 11