目前,我正在使用以下项目:
我的代码是:
$invoice = Invoice::find($id);
foreach($invoice->items as $item) {
$item->subItems;
}
return $invoice;
这很好用,直到发票中有太多的项目并且每个项目有太多的子项目并且PHP返回超时。还有其他更好的解决方案吗?
答案 0 :(得分:1)
首先,我认为您的代码有误。您可能不是$invoice->$items
,而是$invoice->items
。
您的问题的答案可能是急切地加载。代替:
$invoice = Invoice::find($id);
尝试:
$invoice = Invoice::with([
'items' => function ($q) {
$q->with('subItems');
}
])->find($id);
这样,所有内容都将在一个查询中加载。您当前正在执行count($invoice->items) + 1
个查询。这称为N + 1问题,要意识到这一点非常普遍且重要。
答案 1 :(得分:1)
$invoice = Invoice::with(array('items','items.subItems')->where('id',$id)->get();
答案 2 :(得分:0)
在迭代每一项时,更新set_time_limit所允许的线程时间:
$invoice = Invoice::find($id);
$allowed_seconds_per_row = 3;
foreach($invoice->$items as $item){
set_time_limit($allowed_seconds_per_row);
$item->subItems();
}
return $invoice;
这仍然意味着请求将花费大量时间,但是每行迭代只需要$allowed_seconds_per_row
秒。如果一行花费的时间比预期的长,则将超时。
其他选项是将进程移至cli
并调整最大执行时间以解决最坏的情况。