foreach() 参数必须是数组|对象类型,使用 cookie 时在 Laravel 8 中给出的字符串

Posted

技术标签:

【中文标题】foreach() 参数必须是数组|对象类型,使用 cookie 时在 Laravel 8 中给出的字符串【英文标题】:foreach() argument must be of type array|object, string given in Laraval 8 when using cookies 【发布时间】:2022-01-22 06:41:28 【问题描述】:

我正在尝试创建一个在线书店,其中包含一个用户可以存储书籍的愿望清单。我希望通过在 Laravel 中使用 cookie 来创建它。

存储 id 似乎没有问题,但是当我尝试检索它们并使用书籍的 foreach 循环显示列表时(在本例中为书籍的 id),我收到错误“ foreach() 参数必须是数组|对象类型,给定字符串'

在愿望清单控制器中设置 cookie:

    public function store($id)
    
        Cookie::queue('wishlist', $id, 10);

        $book = Book::query()->whereHas('bookCopies', function ($q) use ($id) 
            $q->whereId($id);
        )->first();

        return redirect()->route('books.index', ['id' => $book->id]);
    

获取数据并将其显示在 Wishlist Controller 的视图中:

    public function index()
    
        if (Cookie::has('wishlist')) 
            $books = Book::query()->whereHas('bookCopies', function ($q) 
                $q->whereIn('id', Arr::flatten(Cookie::get('wishlist')));
            )->get();
        

        return response(view('member.wishlist', ['books' => $books ?? []]));
    

web.php 中的路由:

Route::group([
    'prefix' => 'wishlist',
    'as' => 'wishlist'
], function () 
    
    Route::get('index', [WishlistController::class, 'index'])->name('.index');
    Route::post('store/id', [WishlistController::class, 'store'])->name('.store');

);

我如何将 id 发送到 store():

@if($book->firstAvailableBookCopyId())
    <form action=" route('wishlist.store', $book->firstAvailableBookCopyId()) " method="post">
      @csrf
    <button class="text-lg bg-gray-200 rounded-xl p-2 hover:bg-gray-300 cursor-pointer" type="submit" >Wishlist</button>
     </form>
@else
    Empty...
@endif

遍历wishlist.blade.php上的数据:

@forelse($books as $book)                                                     
    <tr>                                                                      
        <td class="w-1/3 text-left py-3 px-3"> $book->title </td>         
        <td class="w-1/3 text-left py-3 px-3"> $book->author->name </td>  
        <td class="text-left py-3 px-3"> $book->genre->title </td>        
        <td class="text-left py-3 px-3"><a                                    
                href=" route('book.show', ['id' => $book->id] )">Open</a> 
        </td>                                                                 
    </tr>                                                                     
@empty                                                                        
    <tr>                                                                      
        <td>                                                                  
            <p>Nothing to show...</p>                                         
        </td>                                                                 
    </tr>                                                                     
@endforelse                                                                   

【问题讨论】:

您还没有指定错误发生的位置,大概是@forelse 行?如果是这种情况,那么只需 var_dump($books) 即可查看它实际包含的内容。 【参考方案1】:

实际上,这个错误出现在 Arr::flatten(Cookie::get('wishlist') 助手中,而不是在刀片的 @foreach 循环中。因为Arr::flatten是接受多维数组转换成单个数组。 但是您正在尝试传递一个实际上是整数或字符串的愿望清单 cookie 值。

因此,您需要将带有 user_id 的愿望清单书 ID 作为愿望清单表存储到数据库中,而不是保存在 cookie 中。

并进行此查询以获取愿望清单书籍:

$wishlist = Wishlist::where('user_id', Auth::id())->pluck('id');

$books = Book::query()->whereHas('bookCopies', function ($q) 
                $q->whereIn('id', $wishlist);
            )->get();

【讨论】:

以上是关于foreach() 参数必须是数组|对象类型,使用 cookie 时在 Laravel 8 中给出的字符串的主要内容,如果未能解决你的问题,请参考以下文章

foreach用法

参数必须是数组还是实现了Countable的对象?

MyBatis--动态SQL(foreach的用法--实现in集合)

count():参数必须是在codeigniter中实现Countable的数组或者对象

使对象可以像数组一样进行foreach循环,要求属性必须是私有

传递给 Illuminate\Database\Eloquent\Model::__construct() 的参数 1 必须是数组类型,给定对象,