Applying multiple php FilterIterator instances in a cascading fashion
Edit

One suggestion is to make your helper class more dynamic. As it currently stands it is heavily tied to each filter class so you could not reuse it in another project. For example, imagine a new project that deals with selling cars. Your Select helper class only knows about orders, services, providers. You'd have to rewrite it to know about cars, prices, colours etc. 

To get around this, you can define a filter property which holds a list of filters. Then, when calling get(), loop over the filters and apply each one. The benefit here is that the helper class is now
unaware of any filter implementations and can be used in any project. 

&lt;?php

/*************************************************/
/******************** FILTERS ********************/
/*************************************************/
class Order extends FilterIterator
{
    private $_value = null;

    public function __construct(Iterator $iterator, $value)
    {
        $this-&gt;_value = $value;
        parent::__construct($iterator);
    }

    public function accept()
    {
        return $this-&gt;current()-&gt;order === $this-&gt;_value;
    }
}

class Future extends FilterIterator
{
    public function __construct(Iterator $iterator)
    {
        parent::__construct($iterator);
    }

    public function accept()
    {
        return $this-&gt;current()-&gt;date &gt; new DateTime();
    }
}

class Date extends FilterIterator
{
    private $_value = null;

    public function __construct(Iterator $iterator, $value)
    {
        $this-&gt;_value = $value;
        parent::__construct($iterator);
    }

    public function accept()
    {
        return $this-&gt;current()-&gt;date === $this-&gt;_value;
    }
}

/*************************************************/
/*************** COLLECTION HELPER ***************/
/*************************************************/
class Helper
{
    private $_items = [];
    private $_filters = [];

    public function __construct(array $items)
    {
        $this-&gt;_items = (new ArrayObject($items))-&gt;getIterator();
    }

    public function filter($filter, $value = null)
    {
        $this-&gt;_filters[] = [$filter =&gt; $value];

        return $this;
    }

    public function get()
    {
        foreach ($this-&gt;_filters as $filter) {
            foreach ($filter as $name =&gt; $value) {

                if ($value) {
                    $this-&gt;_items = new $name($this-&gt;_items, $value);
                } else {
                    $this-&gt;_items = new $name($this-&gt;_items);
                }
            }
        }

        return iterator_to_array($this-&gt;_items);
    }
}

/*************************************************/
/****************** TEST CASES *******************/
/*************************************************/
class Reservation
{
    public $order = null;
    public $date = null;
    public $status = null;

    public function __construct($order, $date, $status)
    {
        $this-&gt;order = $order;
        $this-&gt;date = $date;
        $this-&gt;status = $status;
    }
}

$reservations = new Helper([
    new Reservation(123, new DateTime('+1Day'), 'Active'),
    new Reservation(512, new DateTime('+2Month'), 'Active'),
    new Reservation(456, new DateTime('-6Hour'), 'Pending'),
    new Reservation(789, new DateTime('-17Day'), 'Cancelled'),
    new Reservation(264, new DateTime('+1Hour'), 'Pending'),
    new Reservation(151, new DateTime('+1Year'), 'Active'),
]);

$filtered = $reservations
    -&gt;filter('Future')
    -&gt;filter('Order', 151)
    -&gt;get();

var_dump($filtered);


Final note - I played around with the implementation for a while and found FilterIterators to be rather cumbersome because I had to write a single filter class for each permutation of a property. For example, in a reservation system you'd need the following filters: ByOrder, ByOrderNotEqualTo, ByDate, ByFuture, ByPast, By6MonthsFromNow, ByStatus, ByStatusNotEqualTo, ByCustomerId, etc.

One solution is to add a where method to your helper class which would accept a comparison operator. Again, I point you to Laravel's implementation and a document highlighting its usage. Food for thought. 

EndEdit

If you're looking for a simple method, take a look at Laravel's implementation of their Collection::filter which calls Arr::filter. It provides a clean, chainable way to pass a callback to array_filter. 

Below, is a basic demonstration on how to use it. I've implemented it using ArrayObject but you can use any iterable class. The filter calls will be slightly longer to type out than your implementation since you must define a callback function each time, but it makes the source much cleaner since you don't have to define a separate filter class for every property. 

http://sandbox.onlinephpfunctions.com/code/cea564648d52c702e112d9775d1afe76f41fc810

&lt;?php

class Collection extends ArrayObject
{
    public function filter(callable $callback = null)
    {
        if ($callback) {
            // This will return a new Collection object with the filtered results.
            // Late static binding -  You **could use either `static`
            // or `self` here since both will resolve to Collection.
            // Going with `static` in case you want to extend this class.
            // See - https://stackoverflow.com/q/5197300/296555
            return new static (array_filter($this-&gt;getArrayCopy(), $callback, ARRAY_FILTER_USE_BOTH));
        }

        return new static (array_filter($this-&gt;getArrayCopy()));
    }
}

class Reservation
{
    public $order = null;
    public $date = null;
    public $status = null;

    public function __construct($order, $date, $status)
    {
        $this-&gt;order = $order;
        $this-&gt;date = $date;
        $this-&gt;status = $status;
    }
}

$reservations = new Collection([
    new Reservation(123, new DateTime('+1Day'), 'Active'),
    new Reservation(512, new DateTime('+2Month'), 'Active'),
    new Reservation(456, new DateTime('-6Hour'), 'Pending'),
    new Reservation(789, new DateTime('-17Day'), 'Cancelled'),
    new Reservation(264, new DateTime('+1Hour'), 'Pending'),
    new Reservation(151, new DateTime('+1Year'), 'Active'),
]);

$filtered = $reservations 
    // Active reservations
    -&gt;filter(function ($value, $key) {
        return $value-&gt;status === 'Active';
    })
    // In the future
    -&gt;filter(function ($value, $key) {
        return $value-&gt;date &gt; new DateTime();
    });

var_dump($filtered);


Finally, here's a decent package that took this idea a step further and implements most array functions so you can chain them.