如何解决Nette框架-Nette \ Database \ ResultSet仅实现一种迭代器
我遇到了foreach问题。
如果在第一个foreach {foreach $children as $child}
中返回了一个结果,那么它将起作用。随着更多信息的出现,将弹出一个错误:
Nette\Database\ResultSet
仅实现一种迭代器。
该错误可能是由于在同一个表$children
中查询的每个($invoices
)和第二个(childern
)引起的。我需要列出所有子项(例如$child->firstName
)并为每个子项分配项(例如$invoice->date
$invoice->snackName
)。但是,我无法在查询中取消“ JOIN ON children
”。
输出:
孩子1的名字
- 项目1
- 项目2
孩子2的名字
- 项目1
- 项目2
不知道怎么了? 谢谢
public function actionShow($year,$month)
{
$invoices = $this->database->query('
SELECT
o.date AS date,o.snack AS snack
FROM
diet_orders o
LEFT JOIN children ch ON o.child_id = ch.id
WHERE
ch.user_id = ?
and YEAR (o.date) = ?
and MONTH (o.date) = ?
',$this->getUser()->id,$year,$month,'');
$children = $this->database->table('children')->where('user_id = ?',$this->getUser()->id);
$this->template->invoices = $invoices;
$this->template->children = $children;
}
拿铁
{block content}
{foreach $children as $child}
{$child->fisrtName}
{foreach $invoices as $invoice}
{invoice->snack}
{/foreach}
{/foreach}
{/block}
解决方法
您的推理是正确的。大多数ResultSet
方法返回的Nette\Database
是一种迭代器,因此您不能在循环主体的多次执行中使用它。这是一种优化–循环推进迭代器后,可能会垃圾回收前一行,这对于节省大型数据库表上的内存很有用。
如果确实需要多次遍历一个表,则可以:
- 多次创建
$invoices
- 可能将整个任务移到模板内部的循环中
- 或创建函数以返回结果并在模板中调用
- 或将整个
ResultSet
加载到内存中,例如通过将其转换为数组。这也是documentation的建议:在
ResultSet
上仅可以迭代一次,如果我们需要迭代多次,则必须通过fetchAll()
方法将结果转换为数组。
但是最好的解决方案是尽可能修复它以使用JOIN
。如果您在数据库中使用FOREIGN KEYS
,则当您尝试从其他表访问数据时,可以避免编写原始SQL并使用much nicer interface来透明有效地为您创建JOIN
通过具有外键约束的列。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。