Yii::$App->Session Feature Request

Hello,

I am building a simple shopping cart app in Yii2 and whatever I try I can’t make the following work.

$session = new Session();

$session->open();

$session[‘cart’] = [];

Yii::$app->session[‘cart’][] = $product;

I have tried storing a new Cart object inside $session[‘cart’] with a property $cart which is an array and then wrote:

Yii::$app->session[‘cart’]->cart[] = $product;

And this doesn’t work either because I get the following notice when I try to access the property of the object:

[i] PHP Notice – yii\base\ErrorException

app\controllers\SiteController::actionAdd(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "app\controllers\Cart" of the object you are trying to operate on was loaded before unserialize() gets called or provide a __autoload() function to load the class definition [/i]

Obviously the class definition needs to be loaded before session_start() but, how do I do that in Yii2? I have tried everything.

For now I will move forward with using $_SESSION superglobal instead.

You just have to do this :


Yii::$app->session['cart'][idOfYourProduct] = $product;

But it might not work, so you have to do this :




$products[idOfYourProduct] = $product;

Yii::$app->session['cart'] = $products;



To access to the product :


Yii::$app->session->cart[idOfYourProduct]

Hei,

I tried that and I get another Notice:

http://pastebin.com/sCdRGprB

[color="#FF0000"][i]

PHP Notice – yii\base\ErrorException

Indirect modification of overloaded element of yii\web\Session has no effect[/i][/color]

[color="#FFC0CB"]Yii::$app->session[‘rareCart’][$product[‘id’]] = $product;[/color]

Like as said, you have to do this :




$tmp[$product['id']] = $product;

Yii::$app->session['rareCart'] = $tmp;



Ah, my bad. Ok, it works now but it’s still a little frustrating because I can’t increment it either without getting the same error. So I can’t do:


Yii::$app->session['total_items']++;


            $ti_tmp = Yii::$app->session['total_items'];

            Yii::$app->session['total_items'] = ++$ti_tmp;

I made it work by using another temporary variable but, it’s not at all elegant.

Waaait a minute.


$tmp[$product['id']] = $product;

Yii::$app->session['cart'] = $tmp;

If you do this it doesn’t work. And besides, if the user adds the same product twice the values get overwritten instead of added to the array.

So again, the problem comes down to not being able to do this:


Yii:$app->session['cart'][] = $product;

or


Yii:$app->session['total_items']++;

This will work:


            $ti_tmp = Yii::$app->session['total_items'];

            Yii::$app->session['total_items'] = ++$ti_tmp;

But it’s not elegant… it feels dirty!

But this doesn’t:


        if (isset($_GET['id'])) {

            $product_obj = $model->findOne($_GET['id']);

            $product = $product_obj->attributes;

            $tmp[$product['id']] = $product;

            Yii::$app->session['cart'] = $tmp;

And this feels dirty too, not beautiful, simple. :D

Edit: Unfortunately your code doesn’t build an array under Yii::$app-session[‘cart’] just replaces a single value with another array over and over.

Which is why


$array[] =

or array_push(); are needed. But neither work with Yii::$app->session and I don’t know any other way of pushing to an array.

I’ve found that working with objects+arrays in single statements rather difficult. I would recommend splitting it out into two:




$session = Yii::$app->session;

// do something with $session



Thank you amnah