Reputation: 1318
Can anyone explain why this happens? Side question: is there a way to make it work using DirectoryIterator so the correct objects are stored in $j
and $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:
First time through all seems as expected but, after storing references to each file in $j
, each element appears to lose its reference. (I started out trying to use filter/map functions from this library but reduced the problem down to the listing above.)
Tested with PHP 5.4.27.
Upvotes: 1
Views: 146
Reputation: 1318
What I really wanted to do was along the lines of this:
<?php
use Functional as F;
$i = new DirectoryIterator('.');
$j = F\filter($i, function ($x) { return $x->isDot(); });
looks good, but $j
is not what you might think!
But I can add an extra step...
<?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
is now a cool filtered beer array containing my directory entries.
Upvotes: 0
Reputation: 14628
$x
is an object reference of type DirectoryIterator
, and as a result, all elements in $j
are identical. Once the iterator has finished working, it has nothing to display.
http://www.php.net/manual/en/language.oop5.object-comparison.php
When you attribute a value of an object, the object isn't copied, but the reference to that object is attributed, so they are identical.
Now, when DirectoryIterator
iterates in a foreach()
, the next()
method is called on each iteration, so your $x
is the same reference each time, but the object has changed. But all the references still point to the same object, which, in the end, after the iterations have ended, doesn't refer to any file.
For fun, you can do a:
for($i=1;$i<count($j);$i++) {
var_dump($j[$i-1]===$j[$i]); echo "\n";
}
you should get all lines bool(true)
Upvotes: 2