任何人都能解释为什么会这样吗?附带问题:有没有办法让它使用DirectoryIterator工作,所以正确的对象存储在$j
和$k
?
<?php
// my name is dirtest.php and I live on my own in a directory
$i = new DirectoryIterator(".");
$j = [];
$k = [];
function println($val) {
echo $val . "\n";
}
println('First time:');
foreach ($i as $x) {
$j[] = $x;
println($x->getFilename());
}
println('Second time:');
foreach ($j as $y) {
$k[] = $y->getFilename();
println($y->getFilename());
}
First time:
.
..
dirtest.php
Second time:
.
..
dirtest.php
First time:
.
..
dirtest.php
Second time:
第一次通过所有似乎都符合预期,但是,在$j
中存储对每个文件的引用后,每个元素似乎都会丢失其引用。 (我开始尝试使用this library中的过滤器/地图功能,但将问题缩小到上面的列表。)
使用PHP 5.4.27进行测试。
答案 0 :(得分:2)
$x
是DirectoryIterator
类型的对象引用,因此$j
中的所有元素都相同。迭代器完成工作后,无法显示任何内容。
http://www.php.net/manual/en/language.oop5.object-comparison.php
当您定义对象的值时,不会复制该对象,但会对该对象的引用进行归因,因此它们是相同的。
现在,当DirectoryIterator
在foreach()
中进行迭代时,每次迭代都会调用next()
方法,因此每次$x
都是相同的引用,但是对象已经改变。但是所有引用仍然指向同一个对象,最后,在迭代结束后,它不会引用任何文件。
为了好玩,你可以做:
for($i=1;$i<count($j);$i++) {
var_dump($j[$i-1]===$j[$i]); echo "\n";
}
你应该获得所有行bool(true)
答案 1 :(得分:0)
我真正想要做的就是这样:
<?php
use Functional as F;
$i = new DirectoryIterator('.');
$j = F\filter($i, function ($x) { return $x->isDot(); });
看起来不错,但$j
不是你想象的那样!
但我可以增加额外的一步......
<?php
use Functional as F;
$i = new DirectoryIterator('.');
function deref($xs) {
return F\map($i, function ($x) { return clone $x; });
}
$j = F\filter(
deref($i),
function ($x) { return $x->isDot(); })
);
$j
现在是一个很酷的过滤后的 beer 数组,其中包含我的目录条目。