我想做一个在线书店,里面有一个愿望清单,用户可以在上面存书。我希望通过在Laravel中使用cookie来创建此。
存储id似乎没有问题,但当我尝试检索它们并使用书籍的foreach循环(在本例中为书籍的id)显示列表时,我得到错误“foreach()参数必须是array | object类型,字符串给定”
在愿望清单控制器中设置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发送到存储():
@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
实际上,这个错误在Arr::flatten(Cookie::get('wishlist')
helper中,不在您的刀片的@Foreach
循环中。因为Arr::flatten是接受多维数组转换成单个数组的。但是您正试图传递一个实际上是整数或字符串的愿望列表cookie值。
因此,您需要将具有用户id的愿望列表书id作为愿望列表表存储到数据库中,而不是保存在cookie中。
并进行以下查询以获取愿望清单书籍:
$wishlist = Wishlist::where('user_id', Auth::id())->pluck('id');
$books = Book::query()->whereHas('bookCopies', function ($q) {
$q->whereIn('id', $wishlist);
})->get();