向$_SESSION Cart对象添加元素时出现问题


Issue with adding elements to $_SESSION Cart Object

当我向购物车添加元素时,会话覆盖遇到了一些问题。

$_SESSION["cart"]元素仍然在session中,但是当我添加一个新元素时,它会覆盖之前的元素,如果我更改section并返回商店,它会重置,我不确定为什么会发生这种情况。

我检查了这个线程PHP:在$_SESSION中存储'对象',但我在任何会话修改之前都有session_start()。我还检查了这个线程内部服务器错误500 - session_start(),但检查服务器phpinfo()后,我得到了

Directive               Local Value     Master Value
session.save_handler    files           files

我有三个类,Product, Presentation和Cart。

Presentation有Products, Cart有Presentations。

类产品
class Product {
    private $id;
    private $name;
    private $sku;
    private $weight;
    private $existence;
    private $minimum_existence;
    private $url;
    private $images;
    private $db;
    private $lang;
    public function __construct($id,$lang="es") {
        $this -> id = $id;
        $this -> db = new PDO(DB_CONNECTION,DB_USER,DB_PASS,array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
        $this -> lang = $lang;
        $this -> images = array();
        $this -> get_info();
    }
    public function __destruct() {
        unset($this);
    }
    public function get_info() {
        $info_product = $this -> db -> prepare("SELECT shop_products.*, shop_products_images.* FROM shop_products JOIN shop_products_images ON shop_products.id_product=shop_products_images.id_product WHERE shop_products.id_product=".$this -> id." AND shop_products_images.principal=1");
        $info_product -> execute();
        $info = $info_product -> fetch();
        $this -> id = $info["id_product"];
        $this -> name = $info["product_name_".$this -> lang];
        $this -> sku = $info["product_sku"];
        $this -> weight = $info["product_weight"];
        $this -> existence = $info["product_existence"];
        $this -> minimum_existence = $info["product_minimum_existence"];
        $this -> url = $info["product_url_".$this -> lang];
        $this -> images["original"] = $info["image_original"];
        $this -> images["big"] = $info["image_big"];
        $this -> images["medium"] = $info["image_medium"];
        $this -> images["small"] = $info["image_small"];
        $this -> images["thumbnail"] = $info["image_thumbnail"];
    }
    //
    public function get_name() {
        return $this -> name;
    }
    public function get_sku() {
        return $this -> sku;
    }
    public function get_weight() {
        return $this -> weight;
    }
    public function get_existence() {
        return $this -> existence;
    }
    public function get_minimum_existence() {
        return $this -> minimum_existence;
    }
    public function get_url() {
        return $this -> url;
    }
    public function get_image($size) {
        return $this -> images[$size];
    }
}

类表示

class Presentation {
    private $id;
    private $name;
    private $description;
    private $capacity;
    private $weight;
    private $price;
    private $discount;
    private $url;
    private $images;
    private $products;
    private $db;
    private $lang;
    public function __construct($id,$lang="es") {
        $this -> id = $id;
        $this -> db = new PDO(DB_CONNECTION,DB_USER,DB_PASS,array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
        $this -> lang = $lang;
        $this -> images = array();
        $this -> products = array();
        $this -> get_info();
    }
    public function __destruct() {
        unset($this);
    }
    public function get_info() {
        $info_presentation = $this -> db -> prepare("SELECT * FROM shop_product_presentations WHERE id_presentation=".$this -> id);
        $info_presentation -> execute();
        $info = $info_presentation -> fetch();
        $this -> name = $info["presentation_name_".$this-> lang];
        $this -> description = $info["presentation_description_".$this-> lang];
        $this -> capacity = $info["presentation_capacity"];
        $this -> weight = $info["presentation_weight"];
        $this -> price = $info["presentation_price"];
        $this -> discount = $info["presentation_discount"];
        $this -> url = $info["presentation_url_".$this-> lang];
        $this -> images["original"] = $info["presentation_image_original"];
        $this -> images["medium"] = $info["presentation_image_medium"];
        $this -> images["small"] = $info["presentation_image_small"];
    }
    //
    public function add_product($id_product,$quantity=1) {
        if($this -> get_quantity() < $this -> capacity) {
            if(isset($this -> products[$id_product])) {
                if($quantity > $this -> get_left()) {
                    $quantity = $this -> get_left();
                }           
                $this -> products[$id_product]["quantity"] += $quantity;
                if($this -> products[$id_product]["quantity"] == 0) {
                    unset($this -> products[$id_product]);
                }
            } else {
                $this -> products[$id_product]["product"] = new Product($id_product);
                $this -> products[$id_product]["quantity"] = $quantity;
            }
        } else {
            return false;
        }
    }
    public function total_weight() {
        $weight = $this -> weight;
        foreach($this -> products as $p) {
            $weight += ($p["product"] -> get_weight() * $p["quantity"]);
        }
        return $weight;
    }
    public function display() {
    }
    //
    public function get_name() {
        return $this -> name;
    }
    public function get_description() {
        return $this -> description;
    }
    public function get_capacity() {
        return $this -> capacity;
    }
    public function get_quantity() {
        $x = 0;
        foreach($this -> products as $p) {
            $x += $p["quantity"];
        }
        return $x;
    }
    public function get_left() {
        return $this -> capacity - $this -> get_quantity();
    }
    public function get_weight() {
        return $this -> weight;
    }
    public function get_price() {
        return $this -> price;
    }
    public function get_discount() {
        return $this -> discount;
    }
    public function get_url() {
        return $this -> url;
    }
    public function get_image($size) {
        return $this -> images[$size];
    }
    public function get_products() {
        foreach($this -> products["product"] as $p) {
            $p -> get_info();
        }
        return $this -> products;
    }
}

类车

class Cart {
    private $id;
    private $start_datetime;
    private $end_datetime;
    private $id_customer;
    private $presentations;
    public function __construct($id_customer=0) {
        $this -> id = md5(uniqid(mt_rand()));
        $this -> start_datetime = date("Y-m-d H:i:s");
        $this -> end_datetime = date("Y-m-d H:i:s", strtotime($this -> start_datetime) + 1800);
        $this -> id_customer = $id_customer;
        $this -> presentations = array();
    }
    public function __destruct() {
        unset($this);
    }
    //
    public function add_presentation($presentation) {
        array_push($this -> presentations,$presentation);
        $this -> end_datetime = date("Y-m-d H:i:s", strtotime($this -> end_datetime) + 600);
    }
    public function remove_presentation($index) {
        unset($this -> presentations[$index]);
    }
    public function get_subtotal() {
        $subtotal = 0.00;
        foreach($this -> presentations as $p) {
            $p -> get_info();
            $subtotal += $p -> get_price();
        }
        return number_format($subtotal,2,".","");
    }
    public function get_taxes($percentage) {
        return number_format($this -> get_subtotal() * $percentage,2,".","");
    }
    public function get_total($percentage) {
        return number_format($this -> get_subtotal() + $this -> get_taxes($percentage),2,".","");
    }
    public function get_total_weight() {
        $weight = 0.00;
        foreach($this -> presentations as $p) {
            $weight += $p -> total_weight();
        }
        return number_format($weight,2,".","");
    }
    //
    public function get_id() {
        return $this -> id;
    }
    public function get_start_datetime() {
        return $this -> start_datetime;
    }
    public function get_end_datetime() {
        return $this -> end_datetime;
    }
    public function get_id_customer() {
        return $this -> id_customer;
    }
    public function set_id_customer($id_customer) {
        $this -> id_customer = $id_customer;
    }
    public function get_presentations() {
        return $this -> presentations;
    }

}
head。php文件中的处理程序是:

require_once("lib/dbconfig.php");
    require_once("lib/class.product.php");
    require_once("lib/class.presentation.php");
    require_once("lib/class.cart.php");
session_start();
if(isset($_SESSION["gandj_customer"])) { $id_customer = $_SESSION["gandj_customer"]["id_customer"]; }
    else { $id_customer = 0; }
    if(isset($_SESSION["cart"]))
    {
        if($_SESSION["cart"] -> get_end_datetime() < date("Y-m-d H:i:s"))
        {
            $_SESSION["cart"] = new Cart($id_customer);
        }
        if($_SESSION["cart"] -> get_id_customer() == 0 && $id_customer != 0)
        {
            $_SESSION["cart"] -> set_id_customer($id_customer);
        }
    }
    else
    {
        $_SESSION["cart"] = new Cart($id_customer);
    }
    if($seccion == "shop") {
        switch($_POST["action"]) {
            case "add":
                $pres = new Presentation($_POST["id_presentation"]);
                $pres -> get_info();
                foreach($_POST["cantidad"] as $key => $cantidad) {                  
                    if($cantidad > 0) {
                        $pres -> add_product($key,$cantidad);
                    }   
                }
                $_SESSION["cart"] -> add_presentation($pres);
                header("Location: /shop/");
            break;

        }
    }

我遇到的问题是……

步骤1:我打开商店部分,我的print_r打印出:

Cart Object
(
    [id:private] => c3ceee39137d55cbf6db97b67dc90cdc
    [start_datetime:private] => 2013-06-07 12:46:36
    [end_datetime:private] => 2013-06-07 13:16:36
    [id_customer:private] => 0
    [presentations:private] => Array
        (
        )
)

步骤2:我添加了一个随机的演示文稿,它看起来正确,并且正如函数中所述,它将会话购物车结束时间增加了10分钟。

    Cart Object
    (
        [id:private] => c3ceee39137d55cbf6db97b67dc90cdc
        [start_datetime:private] => 2013-06-07 12:46:36
        [end_datetime:private] => 2013-06-07 13:26:36
        [id_customer:private] => 0
        [presentations:private] => Array
            (
                ...
    this part displays correctly
...
            )
    )

步骤3:我决定从URL再次打开该部分。这是我得到的输出。如果您注意到,原来的datetime没有改变,这使我相信$_SESSION购物车对象保持不变。

Cart Object
(
    [id:private] => c3ceee39137d55cbf6db97b67dc90cdc
    [start_datetime:private] => 2013-06-07 12:46:36
    [end_datetime:private] => 2013-06-07 13:16:36
    [id_customer:private] => 0
    [presentations:private] => Array
        (
        )
)

我的一个假设是,当我将Presentation和Product对象添加到session时,我没有很好地处理它们,但是我以前使用过类似的过程,并且工作得很好。有什么建议吗?

编辑:

过了一会儿,我发现这是一个会话问题,因为原始的Cart对象保持不变,但没有新的添加到会话中。它是在我执行过程时添加的,但它不会在页面中持续存在。我有session_start()无处不在。

我正在处理gettext和其他一些会话变量,我不知道这是否会以任何方式影响

我的问题是数据库。显然,PDO与会话处理有一些冲突,因此将其作为类中的参数传递会造成麻烦。

使用这个类修复了我的问题:https://gist.github.com/tony-landis/31464

我希望它能帮助到一些人:)