Yii 1.1: Using filters with CGridView and CArrayDataProvider


Using filters on CGridView with CActiveDataProvider is easy, but with CArrayDataProvider it is a bit tricky.

To use the filters you have to create a separate model class. I used some code from the following forum topic: link

Note: Normally, when you have an array of CModels, you should use CActiveDataProvider instead!

Here is some example code:


Copy and include this class into your application.

 * Filterform to use filters in combination with CArrayDataProvider and CGridView
 * @see http://www.yiiframework.com/wiki/232/using-filters-with-cgridview-and-carraydataprovider/
class FiltersForm extends CFormModel
     * @var array filters, key => filter string
    public $filters = array();
     * Override magic getter for filters
     * @param string $name
    public function __get($name)
        if (!array_key_exists($name, $this->filters)) {
            $this->filters[$name] = '';
        return $this->filters[$name];
     * Override magic setter for filters
     * @param string $name
     * @param mixed $value
    public function __set($name, $value)
        $this->filters[$name] = $value;
     * Filter input array by key value pairs
     * @param array $data rawData
     * @return array filtered data array
    public function filter(array $data)
        foreach ($data AS $rowIndex => $row) {
            foreach ($this->filters AS $key => $searchValue) {
                if (!is_null($searchValue) AND $searchValue !== '') {
                    $compareValue = null;
                    if ($row instanceof CModel) {
                        if (isset($row->$key) == false) {
                            throw new CException("Property " . get_class($row) . "::{$key} does not exist!");
                        $compareValue = $row->$key;
                    } elseif (is_array($row)) {
                        if (!array_key_exists($key, $row)) {
                            throw new CException("Key {$key} does not exist in array!");
                        $compareValue = $row[$key];
                    } else {
                        throw new CException("Data in CArrayDataProvider must be an array of arrays or an array of CModels!");
                    if (stripos($compareValue, $searchValue) === false) {
        return $data;

(By @KonApaz) If you want to apply full comparisons (>, <, >=, <=, =) use this

if (substr($searchValue, 0, 2) == '<=') {
    if ($compareValue > substr($searchValue, 2)) {
} else if (substr($searchValue, 0, 2) == '>=') {
    if ($compareValue < substr($searchValue, 2)) {
} else if ($searchValue[0] == '<') {
    if ($compareValue >= substr($searchValue, 1)) {
} else if ($searchValue[0] == '>') {
    if ($compareValue <= substr($searchValue, 1)) {
} else if (stripos($compareValue, $searchValue) === false) {


// Create filter model and set properties
$filtersForm=new FiltersForm;
if (isset($_GET['FiltersForm']))
// Get rawData and create dataProvider
$dataProvider=new CArrayDataProvider($filteredData);
// Render
$this->render('index', array(
    'filtersForm' => $filtersForm,
    'dataProvider' => $dataProvider,


$columns = array(
$this->widget('zii.widgets.grid.CGridView', array(

Total 20 comments

#19627 report it
szako at 2015/10/11 05:09am
Empty lines in CGridView


Thanks for the solution, it works flawlessly! Though I experienced the following in 1.1.16:

After filtering, you have empty lines in the result list if you skipped eg. the first 10 rows. You have to reindex the numerical keys.


return $data;


return array_values($data);
#18896 report it
gb5256 at 2015/01/31 06:02pm
Yii2 ?

Does anybody have experience how to do this with yii-2?


#18761 report it
Peppe at 2014/12/31 05:07am
filter row doesn't show

Hi, this is exactly what I needed, but it doesn't run for me. I've implemented the exact code you specified, with just one difference: in the controller, instead of this row, that returns array of active record

$rawData = User::model()->findAll();

I used this one, that returns array of array

$rawData = DatabaseSae::listaAttivita();

I don't have an active record; if so, I don't need to use this code to have filters on grid. However, filter row doesn't appear in the grid. What's wrong?

#16877 report it
marcovtwout at 2014/04/07 03:30am
Re: i would also add strong to the found objects

Please, don't do it like that. Add highlighting at output time, not at filter time.

If you really want to add highlighting while processing the filter, at least store the results in a different array. And don't forget CHtml::encode..

#16859 report it
haimwd at 2014/04/04 11:55am
i would also add strong to the found objects

add this code to make the found string be bold:

if (stripos($compareValue, $searchValue) === false) {
                    } else {
                        $data[$rowIndex][$key] = str_ireplace($searchValue,'<strong>'.$searchValue.'</strong>',$data[$rowIndex][$key]);
#15276 report it
marcovtwout at 2013/10/22 09:05am
Re: RE: Re: RE: Re: is_null

FiltersForm is currently not doing any validation, so you cannot apply any rules. Also, null is a perfectly valid value, it does not have to be rejected.

One possible use case where someone edits your controller action:

if (isset($_GET['FiltersForm']))
// programmer Bob making sure that adminNote cannot be freely searched
if (/*not admin*/)
    $filtersForm->filters['adminNote'] = null;

Ofcourse I agree setting and validating rules is the recommended way of validating search values.

This discussion is becoming too long for the small point I was trying to make, so I'm gonna leave it at this. Conclusion: defensive programming..

#15275 report it
Kostas Apazidis (KonApaz) at 2013/10/22 08:58am
What validators ? (#15274)

According to models (as usually)

the validator for searching is array('attr1, attr2, attr3', 'safe', 'on' => 'search'),

so no other special validator is required (in most cases)

#15274 report it
Kostas Apazidis (KonApaz) at 2013/10/22 08:48am
RE: Re: RE: Re: is_null
foreach ($this->filters AS $key => $searchValue)

protects for null $searchValue

how to inject 'null' value without $key ?

form[attr1] = value1 form[attr2] = value1 if (form[attr3] = value1;) is missing the above foreach not includes the attr3 in the iterator. if form[attr3] has no-value will be empty string '' not null

So do you know how can pass null value (not 'null' string) in this case ?

Also if it nessesar to check the values, using rules and validate method are the suitable way.

#15273 report it
marcovtwout at 2013/10/22 08:06am
Re: RE: Re: is_null

When normally submitted through the html form, yes. But what happens if the value is arbitratily set to null? (for example, a programmer trying to override a certain search value). All results will be filtered. So leave it in there, and remember http://en.wikipedia.org/wiki/Defensive_programming

#15272 report it
Kostas Apazidis (KonApaz) at 2013/10/22 07:55am
RE: Re: is_null

As far as i know (in this part of the code) the $searchValue is always a string (empty or not) So I thing the "is_null" could be ommited

#15271 report it
marcovtwout at 2013/10/22 07:38am
Re: is_null

It's not unexpected that someone would set a search value as null (as in, ignore), so I would definitely leave it in.

#15270 report it
yugene at 2013/10/22 07:25am

is_null was a precaution not to miss anything, so, yes, !== '' should work fine alone. Actually, I started with this check only first in my code, but then added is_null check.

Comparison -- yes, your first variant was a correct one as well :)

btw, don't know why, but new order of vars is easier for me to catch right away to understand if comparison is built correctly.

#15269 report it
Kostas Apazidis (KonApaz) at 2013/10/22 07:00am
RE: update #8

In the updated line

!is_null($searchValue) $searchValue !== '')

I agree with $searchValue !== '' instead empty function http://php.net/manual/en/function.empty.php (empty returns false for the number 0)

But, Is there case that is_null($searchValue) return true in this code ?

I have never seen such a case or I can't remember, dο you?

Thanks :)

#15268 report it
Kostas Apazidis (KonApaz) at 2013/10/22 06:51am
RE: 1560

Hi yugene

In my first update I have the correct inequality http://www.yiiframework.com/wiki/revision/?id=232&r1=5

You have update the same comparison that I wrote in the first time, reversing the order of variables. (Thanks!)

For example substr($searchValue, 2) < $compareValue and $compareValue > substr($searchValue, 2) Is the same thing.

I don't remember why I had agreed with http://www.yiiframework.com/wiki/revision/?id=232&r1=6

Let explain the logic, is a little confusing for a lot of programmers.

if (substr($searchValue, 0, 2) == '<=') {
   if (substr($searchValue, 2) < $compareValue) {
} ...

If: the comparison in text(or whatever) is <=50 (we want the rows of which the specific column is equal or less than 50)

Then: remove the row that ($compareValue > 50 or 50 < $compareValue) that means rows of which the specific column is greater than 50.

So the http://www.yiiframework.com/wiki/revision/?id=232&r1=6 or the currently updated wiki are the correct!

#15260 report it
yugene at 2013/10/22 02:35am

Full comparison is fixed now - there still were some issues with it. I suppose it was just a typo appeared moving the code from your project - in order of variables names at the second level conditions.

#15256 report it
Kostas Apazidis (KonApaz) at 2013/10/21 12:51pm
RE: > < >= <= comparisons

Hi marcovtwout you are right!

the direction of inequality were opposed http://www.yiiframework.com/wiki/revision/?id=232&r1=6

I changed it on my project but I forgot to update the wiki :)

#15164 report it
marcovtwout at 2013/10/14 05:52am
Re: change search criteria

If you want to do more advanced comparisons, you could expand the comparison code, for example like this:

if ($searchValue[0] == '<') {
    // implement
} else if ($searchValue[0] == '>') {
    // implement
} else if (stripos($compareValue, $searchValue) === false) {
#15079 report it
Sharon Lavie at 2013/10/05 05:15am


#15064 report it
Andre Lopez at 2013/10/03 02:58pm
change search criteria

Hi, How could search by criteria: greater than, less than, or just compare dates "from_date, to_date"

thanks in advance, Regards.

#14862 report it
marcovtwout at 2013/09/16 11:40am
Updated wiki article

Updated the code with info from xtremagix. Indeed, it was only working with array of arrays, not array of CModels.

Note: Normally, when you have an array of CModels, you should use CActiveDataProvider instead!

Leave a comment

Please to leave your comment.

Write new article