这是我第一次在这里提问,请耐心等待,因为我不久前刚刚开始编码。不久前,我的同事看到了我的代码
$roles = new Roles();
foreach($roles->get as $role)
{
...irrelevant operation here
}
他评论说,我把查询放在迭代中的方式是错误的,我应该把它改为
$roles = $roles->get();
foreach($roles as $role)
他告诉我,如果我把查询作为数组表达式放在foreach循环中,它会在每个循环中引用数据库,最终会减慢整个网站的速度。我想知道这是真是假,以及背后的逻辑。
$roles->get();打开数据库连接,进行查询,关闭连接。
每个到DB的连接(通常)都是到另一个主机的TCP连接,如果你把它放在一个循环中,它会被调用(n)次。通过让每次迭代都等待DB连接,可以降低循环的速度。如果您一次获取所有数据(如$roles->all()),它会将数据放入RAM,而不需要调用DBforeach项。
希望它能帮助
在foreach
循环中,PHP获取可迭代变量一次,并使用内部迭代器对其进行处理。您同事的反对意见适用于简单的for
循环,其中每次迭代前都执行延续条件。
您可以轻松构建一个测试用例:
<?php
class testClass
{
private
$_iteratable = ['a', 'b', 'c'];
public function get()
{
echo "get called<br>'n";
return $this->_iteratable;
}
}
echo "foreach<br>'n";
$obj = new testClass();
foreach($obj->get() as $key => $value)
{
echo "$key: $value<br>'n";
}
/* OUTPUT:
foreach
get called
0: a
1: b
2: c
*/
echo "<p>for<br>'n";
$obj = new testClass();
for($i = 0; $i < count($obj->get()); $i++)
{
echo "$i: {$obj->get()[$i]}<br>'n";
}
/* OUTPUT:
for
get called
get called
0: a
get called
get called
1: b
get called
get called
2: c
get called
?>
为了提高性能,您可以使用foreach($iteratable as &$reference)
,因为每次迭代只复制对数据的引用,而不是可能更大的数据值。这样做,您将处理传递给foreach循环的原始数据,这意味着:您甚至可以操作该数据。如果按值使用foreach,则将处理副本,并且可以在不影响原始数据的情况下修改工作值。
之间没有显著差异
$roles = $roles->get();
foreach($roles as $role)
和
foreach($roles->get() as $role)
在这两种情况下CCD_ 4将仅被调用一次。这意味着数据库连接将只执行一次。