Laravel中优化发票展示及数组存储数据的技术问题
问题解答
一、优化发票展示逻辑
当前你的Faktor表中每条记录对应一个商品,直接循环所有记录会重复显示用户信息,可通过以下两种场景优化:
1. 单用户发票场景(如当前登录用户的发票)
控制器层:
先单独获取用户信息,再查询该用户的所有商品记录:
public function bill() { $user = Auth::user(); // 获取当前用户的所有发票商品 $invoiceItems = Faktor::where('user_id', $user->id)->get(); return view('bill', compact('user', 'invoiceItems')); }
视图层:
先一次性展示用户姓名、手机号,再循环展示商品列表:
{{-- 用户信息区域(仅显示一次) --}} <div class="invoice-header"> <p>用户姓名:{{ $user->name }}</p> <p>手机号:{{ $user->phone }}</p> </div> {{-- 商品列表区域 --}} <div class="invoice-products"> @foreach($invoiceItems as $item) <div class="product-item"> <p>商品名称:{{ $item->name }}</p> <p>单价:{{ $item->price }}</p> <p>数量:{{ $item->quantity }}</p> </div> @endforeach </div>
2. 多用户发票场景(展示多个用户的发票)
控制器层:
通过groupBy按用户ID分组,同时预加载用户关联数据避免N+1查询:
public function bills() { // 按user_id分组,预加载user关联模型 $groupedInvoices = Faktor::with('user')->get()->groupBy('user_id'); return view('bills', compact('groupedInvoices')); }
视图层:
循环每个用户的分组,先展示用户信息,再展示该用户的所有商品:
@foreach($groupedInvoices as $userId => $items) <div class="invoice-card"> {{-- 单用户信息 --}} <p>用户姓名:{{ $items->first()->user->name }}</p> <p>手机号:{{ $items->first()->user->phone }}</p> {{-- 该用户的商品列表 --}} <div class="products"> @foreach($items as $item) <p>{{ $item->name }} - 单价:{{ $item->price }} - 数量:{{ $item->quantity }}</p> @endforeach </div> </div> @endforeach
二、Laravel中数组存储的常见方式
1. 内存临时存储
直接定义数组变量,或使用Laravel的Collection(更便捷的数组操作工具):
// 普通数组 $products = [ ['product_id' => 1, 'name' => 'i9 gen12', 'price' => 1000], ['product_id' => 2, 'name' => 'ssd', 'price' => 1000] ]; // 转换为Collection,支持筛选、排序等操作 $productCollection = collect($products); // 示例:筛选价格大于500的商品 $highPriceProducts = $productCollection->where('price', '>', 500);
2. 存储到Session中
用于临时保存用户会话数据(比如购物车):
// 存储数组到Session $cart = [ ['product_id' => 1, 'name' => 'i9 gen12', 'quantity' => 1, 'price' => 1000] ]; // 方法1:通过request对象 $request->session()->put('cart', $cart); // 方法2:使用辅助函数 session(['cart' => $cart]); // 获取Session中的数组 $cart = session('cart');
3. 存储到数据库中
如果需要将数组持久化到数据库,可使用json类型字段,并在模型中配置类型转换:
1)数据库迁移(创建json字段):
Schema::create('faktors', function (Blueprint $table) { // 其他字段... $table->json('extra_data')->nullable(); // 存储数组的json字段 });
2)模型配置类型转换:
在Faktor模型中设置$casts,自动将json字段转为数组:
class Faktor extends Model { protected $casts = [ 'extra_data' => 'array', // 存入时自动转json,取出时自动转数组 ]; }
3)存储与读取:
// 存储数组 $faktor = Faktor::find(1); $faktor->extra_data = ['color' => 'black', 'size' => 'L']; $faktor->save(); // 读取数组 $extraData = $faktor->extra_data; echo $extraData['color']; // 输出black
额外优化:批量插入商品记录
你当前循环调用Faktor::create()的方式效率较低,可改为批量插入减少数据库请求:
public function ad(Request $request) { $products = $request->session()->get('cart'); $userId = Auth::id(); // 组装批量插入的数据 $insertData = collect($products)->map(function ($product) use ($userId) { return [ 'user_id' => $userId, 'product_id' => $product['product_id'], 'name' => $product['name'], 'quantity' => $product['quantity'], 'price' => $product['price'], 'created_at' => now(), 'updated_at' => now() ]; })->toArray(); // 批量插入 Faktor::insert($insertData); return redirect('bill'); }
内容的提问来源于stack exchange,提问作者codeLover
相关产品推荐
相关产品推荐

