# RecursiveFilterItrator possible issues with inheritance

- Thread: https://externals.io/message/43862
- Original archive: https://news-web.php.net/php.internals/43862
- Started by Ralph Schindler on 2009-05-06T15:16:19+00:00
- Messages: 3
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #43862 — Ralph Schindler — 2009-05-06T15:16:19+00:00

URL: https://externals.io/message/43862#43862

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

---

## #43863 — Etienne Kneuss — 2009-05-06T15:35:46+00:00

URL: https://externals.io/message/43862#43863 · In reply to: #43862

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 - 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
>
>
>
>
> --
> 
> 
>
>



-- 
Etienne Kneuss
http://www.colder.ch

Men never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal

---

## #43865 — Etienne Kneuss — 2009-05-07T00:37:43+00:00

URL: https://externals.io/message/43862#43865 · In reply to: #43863

Hello,


> Hello,
>
> 
> > […]
>
> This is a bug, could you please report it and assign it to me ?
>
> Thanks,
>
> > […]

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

> > […]
>
>
>
> --
> Etienne Kneuss
> http://www.colder.ch
>
> Men 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
