Php Nette framework-Nette\Database\ResultSet仅实现单向迭代器
我遇到了foreach的问题。 如果在第一个foreachPhp Nette framework-Nette\Database\ResultSet仅实现单向迭代器,php,nette,Php,Nette,我遇到了foreach的问题。 如果在第一个foreach{foreach$children as$child}中返回一个结果,则该结果有效。由于存在更多错误,会弹出一个错误: Nette\Database\ResultSet只实现单向迭代器 该错误可能是由于在同一个表中查询每个人的第一个($children)和第二个($invoices)引起的。我需要列出所有子项(例如$child->firstName)并为每个子项分配项目(例如$invoice->date$invoice->snackNam
{foreach$children as$child}
中返回一个结果,则该结果有效。由于存在更多错误,会弹出一个错误:
Nette\Database\ResultSet
只实现单向迭代器
该错误可能是由于在同一个表中查询每个人的第一个($children
)和第二个($invoices
)引起的。我需要列出所有子项(例如$child->firstName
)并为每个子项分配项目(例如$invoice->date
$invoice->snackName
)。但是,我无法取消查询中的“加入子项”
”
输出:
子1名称
- 项目1
- 项目2
- 项目1
- 项目2
你的推理是正确的。大多数
Nette\Database
方法返回的ResultSet
是单向迭代器,因此不能在循环体的多次执行中使用它。这是一种优化——一旦循环推进迭代器,前一行就可能被垃圾收集,这对于节省大型数据库表的内存非常有用
如果确实需要对一个表进行多次迭代,可以:
- 多次创建
$invoices
- 可能会将整个分配移动到模板内的循环中
- 或者创建返回该结果并在模板中调用的函数
- 或者将整个
加载到内存中,例如将其转换为数组。这也是委员会的建议: 在ResultSet
只能迭代一次,如果需要多次迭代,则需要通过ResultSet上
方法将结果转换为数组fetchAll()
但最好的解决方案是,如果可能的话,将其修复为使用
JOIN
s。如果在数据库中使用外键
,则当您试图通过带有外键约束的列访问其他表中的数据时,可以避免编写原始SQL,并使用将为您透明高效地创建联接的。大多数Nette\Database
方法返回的ResultSet
是单向迭代器,因此不能在循环体的多次执行中使用它。这是一种优化——一旦循环推进迭代器,前一行就可能被垃圾收集,这对于节省大型数据库表的内存非常有用
如果确实需要对一个表进行多次迭代,可以:
- 多次创建
$invoices
- 可能会将整个分配移动到模板内的循环中
- 或者创建返回该结果并在模板中调用的函数
- 或者将整个
ResultSet
加载到内存中,例如将其转换为数组。这也是委员会的建议:
在ResultSet上
只能迭代一次,如果需要多次迭代,则需要通过fetchAll()
方法将结果转换为数组
但最好的解决方案是,如果可能的话,将其修复为使用JOIN
s。如果您在数据库中使用外键
,当您试图通过带有外键约束的列访问其他表中的数据时,可以避免编写原始SQL,并使用将为您透明高效地创建联接的SQL语句。请更正问题的第二段。这不是完全可以理解的,也不是用英语写的。请更正问题的第二段。这不是完全可以理解的,也不是用英语写的。谢谢。我在您编写时使用了fetchAll()
,它可以正常工作。我不明白网络中的连接。这就是我编写原始SQL的原因。我来看看文件,谢谢。我在您编写时使用了fetchAll()
,它可以正常工作。我不明白网络中的连接。这就是我编写原始SQL的原因。我来看看文档。
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}