Symfony2在会话中存储多个值

时间:2015-04-20 14:23:20

标签: php symfony session

我正在尝试在我的会话中存储多个值(产品),以便我可以在一个篮子中显示它们。但由于某种原因,它只存储一种产品..

在第一页控制器中,我创建了一个数组,我将在稍后存储我选择的产品:

public function indexAction()
    {

            $em = $this->getDoctrine()->getManager();
            $products = $em->getRepository('MpShopBundle:Product')->findAll();

            $session = $this->getRequest()->getSession();

            $item = array();

            $session->set('itemCart', $item);

               return $this->render('MpShopBundle:Frontend:index.html.twig',  array(
               'products'=>$products       
               ));

    }

然后,当用户选择产品时,将打开包含产品详细信息的新页面(产品由ID选择)。然后,如果用户将产品添加到购物车,他将被带到购物篮页面,我将产品保存在带有会话的数组中:

public function viewAction($id)
    {


        $em = $this->getDoctrine()->getManager();
        $product = $em->getRepository('MpShopBundle:Product')->find($id);

        $session = $this->getRequest()->getSession();

        $itemCart = $session->get('itemCart');

        array_push($itemCart, $product);

        $session->set('itemCart', $itemCart);

        return $this->render('MpShopBundle:Frontend:product_details.html.twig', array(
        'product'=>$product
        ));

    }

在购物篮页面中,我得到了产品:

public function summaryAction()
    {


            $em = $this->getDoctrine()->getManager();
            $products = $em->getRepository('MpShopBundle:Product')->findAll();

            $session = $this->getRequest()->getSession();
            $itemCart = $session->get('itemCart');

               return $this->render('MpShopBundle:Frontend:product_summary.html.twig',  array(
               'products'=>$products,
               ));
    }

现在在我的树枝上,我就像这样展示它们。首先,我得到了产品:{% set items = app.session.get('itemCart') %}。然后我循环浏览它们并尝试显示:

  {% for item in items %}
                <tr>
                  <td> <img width="60" src="{{ asset('bundles/mpFrontend/assets/products/4.jpg') }}" alt=""/></td>

                  <td>{{ item.model }}</td>
                  <td>
                    <div class="input-append"><input class="span1" style="max-width:34px" placeholder="1" id="appendedInputButtons" size="16" type="text"><button class="btn" type="button"><i class="icon-minus"></i></button><button class="btn" type="button"><i class="icon-plus"></i></button><button class="btn btn-danger" type="button"><i class="icon-remove icon-white"></i></button>             </div>
                  </td>
                  <td>$120.00</td>
                  <td>$25.00</td>
                  <td>$15.00</td>
                  <td>$110.00</td>
                </tr>

                {% endfor %}

显示第一个产品。当我返回并选择其他产品时,新产品与旧产品重叠,是唯一显示的产品。为什么呢?

发现问题。如何修复它? 好的,我想我发现了我的问题。我只得到一个值,因为当我将我的第一个产品添加到购物篮时,我回到我的索引页面选择另一个产品myy indexController $item = array();部分并使我的数组再次为空。那就是问题所在。但是,如果我选择第一个产品,只需浏览一下而无需重新加载页面并添加新产品就可以了。那么我可以用indexController做些什么来让我每次回去都不会清空我的购物车?

2 个答案:

答案 0 :(得分:1)

我认为您应该使用

将新项目添加到购物车阵列
$item[] = $product;

而不是

array_push($itemCart, $product);

From PHP's manual:

注意:如果使用array_push()向数组添加一个元素,最好使用$ array [] =,因为这样就没有调用函数的开销。

注意:如果第一个参数不是数组,array_push()将发出警告。这与创建新数组的$ var []行为不同。

由于你的数组为空启动,我不相信你在viewAction控制器中收到一个数组。我会将viewAction更改为:

$itemCart = $session->get('itemCart');
if(!is_array($itemCart){
    $itemCart = array();
}
$itemCart[] = $prodcut;

$session->set('itemCart', $itemCart);

答案 1 :(得分:1)

嗯,我认为最基本的解决方案可以是:

public function indexAction()
{
    ...
    if (!$session->get('itemCart')) {
         $session->set('itemCart', array());
    } 

然后我相信在这些控制器中自由地抽象管理会话数据会更好,最好将它包装在专用服务和/或事件逻辑中,并在控制器中使用它。这样就可以避免代码重复,一次性获得更好的可重用代码和责任。

- - - - - - - - EDIT2

你现在要问的是一个长篇故事,也许我不是最好的解释它。

我的意思(只是一个想法,而不是必须做的事情)是:

//IndexAction method

// You could "wrap" this part of the code:
$session = $this->getRequest()->getSession();
$item = array();
$session->set('itemCart', $item);

// with a service (see Symfony DOC) like "CartSession" or 
// simply "Cart" and use it there like:
$this->cartSession->init();
// or  
$this->cart->init();
// And inside the init method you can use the logic you want; 
// Any further changes or if you want to move the session from $_SESSION to another storage mechanism, 
// this doesn't impact on your controller code but only inside your service. 

// viewAction method

// You could "wrap" this part of the code:
$session = $this->getRequest()->getSession();
$itemCart = $session->get('itemCart');
array_push($itemCart, $product);
$session->set('itemCart', $itemCart);

// inside the same service previously defined and used in indexAction
$this->cart->add($itemCart);

但是我可以建议阅读一些关于:

的内容