PHP说取消设置临时foreach变量以防止出现一些问题。但对于像这样的对象集合,它不会取消集合中的原始对象吗?或者不是?
内置的IteratorAggregate接口允许您指定如何在foreach循环中处理类对象。这里,“collection”类为foreach循环提供了$ things数组的thing
个对象。在执行foreach($collection as $thing)
时,每个$ thing将是$ collection的$ things数组中的thing
对象。
class collection implements IteratorAggregate {
protected $things = array();
public function addAThing(thing $thing) {
$this->things[$thing->getId()] = $thing;
}
/**
* For IteratorAggregate
*/
public function getIterator() {
return new ArrayIterator($this->things);
}
}
class thing {
$number = 0;
public function __construct($number) {
$this->number = (int)$number;
}
public function getNumber() {
return $this->number;
}
}
$coll = new collection();
$coll->addAThing(new thing(1));
$coll->addAThing(new thing(3));
$coll->addAThing(new thing(4));
$coll->addAThing(new thing(24));
foreach($coll as $thing) {
echo $thing->getNumber();
}
unset($thing); // To unset, or not to unset?
答案 0 :(得分:1)
每个循环都会将一个新对象放入$thing
,这意味着先前的$thing
将被孤立并最终被PHP收集垃圾。
垃圾收集是一项昂贵的工作,通常你不应该强迫PHP去做 - 当它认为内存可能越来越紧时它会自己做。可能有一些原因导致PHP猜错了,或者你知道一个内存昂贵/时间关键的操作即将出现并且想要确保它没有被垃圾收集运行暂停。
评论后续:
取消设置引用并不会取消引用指向的原始内容:
php > $x = 7;
php > $y = &$x;
php > var_dump($x, $y);
int(7)
int(7)
php > unset($y);
php > var_dump($x, $y);
PHP Notice: Undefined variable: y in php shell code on line 1
int(7)
NULL
请注意$ x是否仍然存在且具有原始值。然而,$ y已经消失了。这同样适用于foreach循环中的引用:
php > $x = array(1,2,3);
php > foreach($x as $y) { if ($y == 2) { unset($y); } } // no references here
php > var_dump($x);
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
php > foreach($x as &$y) { if ($y == 2) { unset($y); } } // note: $y is now a reference
php > var_dump($x);
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
&int(3)
}
请注意,2
元素再次未从原始数组中删除。这同样适用于对象/更复杂的事物:
php > $x = array(new StdClass(), new StdClass());
php > foreach($x as $y) { unset($y); }
php > var_dump($x);
array(2) {
[0]=>
object(stdClass)#1 (0) {
}
[1]=>
object(stdClass)#2 (0) {
}
}
php > var_dump($y);
PHP Notice: Undefined variable: y in php shell code on line 1
NULL
php > foreach($x as $y) { /* do nothing */ }
php > var_dump($x, $y);
array(2) {
[0]=>
object(stdClass)#1 (0) {
}
[1]=>
object(stdClass)#2 (0) {
}
}
object(stdClass)#2 (0) {
}
php > unset($y);
php > var_dump($x, $y);
PHP Notice: Undefined variable: y in php shell code on line 1
array(2) {
[0]=>
object(stdClass)#1 (0) {
}
[1]=>
object(stdClass)#2 (0) {
}
}
NULL
答案 1 :(得分:0)
关于foreach的推荐仅供参考。
http://php.net/manual/en/control-structures.foreach.php
foreach (array(1, 2, 3, 4) as &$value) {
$value = $value * 2;
}
警告
$ value的引用和最后一个数组元素仍然保留在 foreach循环。建议通过unset()来销毁它。
您的代码没有引用,您不必取消设置临时变量。
P.S。你知道,重读后,我认为你的问题不正确。听起来像#34; php有功能,我应该使用它吗?"。 Unset
只是语言的一部分,您必须决定在哪里使用它。你已经掌握了常见的“陷阱”和#34;参考和foreach。但即使在我的例子中使用或不使用取决于任务。例如:循环后需要change last value。如果没有设置,你需要额外的行和额外的函数调用。
$array = array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
foreach ($array as &$value) {
$value = $value * 2;
}
unset($value);
end($array);
$key = key($array);
$array[$key]++;
Whitout未设置你只需要改变价值。
$array = array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
foreach ($array as &$value) {
$value = $value * 2;
}
$value++;