Hi all,
I'd like to confirm something as a bug and/or design issue.
Currently, its difficult to extend RecursiveFilterIterator() with
additional __construct() arguments (for configuring its behavior). The
reason its difficult is b/c when getChildren() is called, a new instance
of the RFI is created (only way you'd know this is if you look into the
source of RFI).
Ideally, this code would work:
$rArray = array('a' => array('ab', 'ac', 'ad' => array('ada', 'adc')),
'b' => array('bb', 'bc'));
$ri = new RecursiveArrayIterator($rArray);
$filter = new MyRFI($ri, 'argument');
$iterator = new RecursiveIteratorIterator($filter);
foreach ($iterator as $key => $item) {
echo $key . ' - ' . $item . PHP_EOL;
}
class MyRFI extends RecursiveFilterIterator
{
protected $_otherArg = null;
public function __construct($iterator, $otherArg = null)
{
$r = new ReflectionClass($this);
$this->_otherArg = $otherArg;
parent::__construct($iterator);
}
public function accept()
{
echo ($this->_otherArg) ? 'Arg Present' : 'Arg NOT Present';
echo PHP_EOL;
return true;
}
The current output would be:
~/tmp/test-rii-filter$ php test-rii-problem.php
Arg Present
Arg NOT Present
0 - ab
Arg NOT Present
1 - ac
Arg NOT Present
Arg NOT Present
0 - ada
Arg NOT Present
1 - adc
Arg Present
Arg NOT Present
0 - bb
Arg NOT Present
1 - bc
The ideal output would be:
Arg Present
Arg Present
0 - ab
Arg Present
1 - ac
Arg Present
Arg Present
0 - ada
Arg Present
1 - adc
Arg Present
Arg Present
0 - bb
Arg Present
1 - bc
The only proposed change I could would be to make the getChildren()
inside of RecursiveFilterIterator use clone & add a method called
setIterator() instead of Reflection::newInstance($iterator)
Is this possible? Or is extending and overriding getChildren() the best
strategy here?
Reason I post is b/c it seems like using clone/setIterator() would
facilitate better inheritance / better polymorphism. And since the
implementation is in the extension, the typical developer would
generally not understand how getChildren() really works under the hood.
Thanks,
Ralph
Hello,
Hi all,
I'd like to confirm something as a bug and/or design issue.
This is a bug, could you please report it and assign it to me ?
Thanks,
Currently, its difficult to extend RecursiveFilterIterator() with additional
__construct() arguments (for configuring its behavior). The reason its
difficult is b/c when getChildren() is called, a new instance of the RFI is
created (only way you'd know this is if you look into the source of RFI).Ideally, this code would work:
$rArray = array('a' => array('ab', 'ac', 'ad' => array('ada', 'adc')), 'b'
=> array('bb', 'bc'));$ri = new RecursiveArrayIterator($rArray);
$filter = new MyRFI($ri, 'argument');
$iterator = new RecursiveIteratorIterator($filter);foreach ($iterator as $key => $item) {
echo $key . ' - ' . $item . PHP_EOL;
}class MyRFI extends RecursiveFilterIterator
{
protected $_otherArg = null;public function __construct($iterator, $otherArg = null)
{
$r = new ReflectionClass($this);
$this->_otherArg = $otherArg;
parent::__construct($iterator);
}public function accept()
{
echo ($this->_otherArg) ? 'Arg Present' : 'Arg NOT Present';
echo PHP_EOL;
return true;
}The current output would be:
~/tmp/test-rii-filter$ php test-rii-problem.php
Arg Present
Arg NOT Present
0 - ab
Arg NOT Present
1 - ac
Arg NOT Present
Arg NOT Present
0 - ada
Arg NOT Present
1 - adc
Arg Present
Arg NOT Present
0 - bb
Arg NOT Present
1 - bcThe ideal output would be:
Arg Present
Arg Present
0 - ab
Arg Present
1 - ac
Arg Present
Arg Present
0 - ada
Arg Present
1 - adc
Arg Present
Arg Present
0 - bb
Arg Present
1 - bcThe only proposed change I could would be to make the getChildren() inside
of RecursiveFilterIterator use clone & add a method called setIterator()
instead of Reflection::newInstance($iterator)Is this possible? Or is extending and overriding getChildren() the best
strategy here?Reason I post is b/c it seems like using clone/setIterator() would
facilitate better inheritance / better polymorphism. And since the
implementation is in the extension, the typical developer would generally
not understand how getChildren() really works under the hood.Thanks,
Ralph--
--
Etienne Kneuss
http://www.colder.ch
Men never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal
Hello,
Hello,
Hi all,
I'd like to confirm something as a bug and/or design issue.
This is a bug, could you please report it and assign it to me ?
Thanks,
Currently, its difficult to extend RecursiveFilterIterator() with additional
__construct() arguments (for configuring its behavior). The reason its
difficult is b/c when getChildren() is called, a new instance of the RFI is
created (only way you'd know this is if you look into the source of RFI).Ideally, this code would work:
$rArray = array('a' => array('ab', 'ac', 'ad' => array('ada', 'adc')), 'b'
=> array('bb', 'bc'));$ri = new RecursiveArrayIterator($rArray);
$filter = new MyRFI($ri, 'argument');
$iterator = new RecursiveIteratorIterator($filter);foreach ($iterator as $key => $item) {
echo $key . ' - ' . $item . PHP_EOL;
}class MyRFI extends RecursiveFilterIterator
{
protected $_otherArg = null;public function __construct($iterator, $otherArg = null)
{
$r = new ReflectionClass($this);
$this->_otherArg = $otherArg;
parent::__construct($iterator);
}public function accept()
{
echo ($this->_otherArg) ? 'Arg Present' : 'Arg NOT Present';
echo PHP_EOL;
return true;
}The current output would be:
~/tmp/test-rii-filter$ php test-rii-problem.php
Arg Present
Arg NOT Present
0 - ab
Arg NOT Present
1 - ac
Arg NOT Present
Arg NOT Present
0 - ada
Arg NOT Present
1 - adc
Arg Present
Arg NOT Present
0 - bb
Arg NOT Present
1 - bcThe ideal output would be:
Arg Present
Arg Present
0 - ab
Arg Present
1 - ac
Arg Present
Arg Present
0 - ada
Arg Present
1 - adc
Arg Present
Arg Present
0 - bb
Arg Present
1 - bcThe only proposed change I could would be to make the getChildren() inside
of RecursiveFilterIterator use clone & add a method called setIterator()
instead of Reflection::newInstance($iterator)Is this possible? Or is extending and overriding getChildren() the best
strategy here?Reason I post is b/c it seems like using clone/setIterator() would
facilitate better inheritance / better polymorphism. And since the
implementation is in the extension, the typical developer would generally
not understand how getChildren() really works under the hood.
Sorry for the false hope, it is indeed how it's supposed to work and
not a bug. Since the new iterator is instanciated directly inside
getChildren, you can't magically have new arguments to your
constructor and have them filled appropriately.
But you can basically implement all features you want by simply
overriding getChildren.
Clone + setiterator could also work, but changing that would introduce
BC breaks, and I'm not sure it would make more sense than what we have
now.
Regards
Thanks,
Ralph--
--
Etienne Kneuss
http://www.colder.chMen never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal
--
Etienne Kneuss
http://www.colder.ch
Men never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal