首页 > 解决方案 > 如何从会话中提取,编辑它然后将其重新插入 Laravel?

问题描述

我正在尝试创建一个购物车控制器。我正在使用 Laravel 的Http Session来实现这一点。但是,我收到此错误:

Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_ERROR) 不能使用带字符串偏移的赋值操作符

以前的例外 - 非法字符串偏移量“数量”(0)

这是我当前导致此错误的代码:

public function addOrUpdate(Request $request) {
    if(!isset($request->productName) && !isset($request->productId))
        return Redirect::back()->withErrors(['Please fill in all the required fields.'])->withInput();

    # Init cart if not yet set
    if(!$request->session()->has('cart'))
        $request->session()->put('cart', []);

    # Pull and delete the old value
    $product = $request->session()->pull("cart.{$request->productId}", "cart.{$request->productId}");

    # If we managed to pull anything, lets increase the quantity
    if(isset($product)) {
        $product['quantity']++;
        $request->session()->push('cart', [$request->productId => $product]);
        var_dump($request->session('cart')); # Confirmation
        return true;
    }

    # Nothing was pulled, lets add it
    $request->session()->push('cart', [$request->productId => [
        'productName'   => $request->productName,
        'quantity'      => 1
    ]]);
    var_dump($request->session('cart')); # Confirmation
    return true;
}

当我var_dump($product)在通过isset()条件之前执行 a 时,它给了我一个string(6) "cart.1".

如果我var_dump(session('cart'))在通过isset()条件之前做了一个,它会给我(带有测试数据)

array(1) { [0]=> array(1) { [1]=> array(2) { ["productName"]=> string(3) "foo" ["quantity"]=> int(1) } } }

在 Laravel 的文档中,

#检索和删除项目

pull 方法将在单个语句中从会话中检索和删除一个项目:

$value = $request->session()->pull('key', 'default');

如何获取存储在 ID 中的当前产品、删除它、编辑它然后重新插入它,因为这似乎返回了我想要获取的数组。

更新

public function addOrUpdate(Request $request) {
    if(!isset($request->productName) && !isset($request->productId))
        return Redirect::back()->withErrors(['Please fill in all the required fields.'])->withInput();

    # Init cart if not yet set
    if(!session()->has('cart'))
        session()->put('cart', []);

    $cart = session('cart');

    if(isset($cart[$request->productId])){
        # Pull and delete the old value
        $product = session()->pull("cart.{$request->productId}", "cart.{$request->productId}");

        # If we managed to pull anything, lets increase the quantity
        if(isset($product)) {
            $product['quantity']++;
            session()->push("cart.{$request->productId}", $product);
            echo 'Updated';
            dd(session('cart'));
            return true;
        }

        return false;
    }

    # Nothing was pulled, lets add it
    session()->push("cart.{$request->productId}",  [
        'productName'   => $request->productName,
        'quantity'      => 1
    ]);
    echo 'Added';
    dd(session('cart'));
    return true;
}

这现在似乎正在添加正确的信息,但从未更新。我需要参加flash()会议吗?

标签: phplaravellaravel-5

解决方案


这里的主要问题是 Laravel 中的 HTTP 会话只使用一次。为了保持价值,必须flash()reFlash()购物车。

public function addOrUpdate(Request $request) {
    if(!isset($request->productName) && !isset($request->productId))
        return Redirect::back()->withErrors(['Please fill in all the required fields.'])->withInput();

    # Init cart if not yet set
    if(!session()->has('cart')) {
        session()->put('cart', []);
        session()->flash('cart');
    }

    $cart = session('cart');

    if(isset($cart[$request->productId])){
        # Pull and delete the old value
        $product = session()->pull("cart.{$request->productId}", "cart.{$request->productId}");

        # If we managed to pull anything, lets increase the quantity
        if(isset($product)) {
            $product[0]['quantity']++;
            session()->push("cart.{$request->productId}", $product[0]);
            session()->reFlash('cart');
        }
    } else {

        # Nothing was pulled, lets add it
        session()->push("cart.{$request->productId}",  [
            'productName'   => $request->productName,
            'quantity'      => 1
        ]);
        session()->reFlash('cart');

    }
}

这里唯一的问题是,如果用户导航到其他任何地方,其他路线不会重新刷新购物车。所以这个必须执行。

我通过在我的文件boot()方法中添加这行代码来实现这一点:RouteServiceProvider.php

if(session()->has('cart'))
    session()->reFlash('cart');

推荐阅读