[Solved] Parametrizing Select Fields In Criteria For Ar?

I’m building a small API, and would like to allow the requester to specify fields to obtain in the API call.

Something like http://domain.com/api/model?fields=id,name,description

And I would later insert that into a criteria object to use in the AR. Ex:

$criteria=new CDbCriteria();



The problem with the above is that I could, in theory (I actually did a SELECT COUNT(*) FROM Table and it was injected), SQL inject the fields. Something like:

http://domain.com/api/model?fields=SELECT * FROM USER –

I started to white list the available fields, but it seems so dirty and cluttered that way. I was wondering if there is a way to parametrize the select fields? I tried the following but I just get exceptions “Invalid parameter number: mixed named and positional parameters”. Since the fields and the models are dynamic, I can’t just hard code the parameters.

I was hoping that something like this would work, but no luck:

criteria=new CDbCriteria();



$criteria->params=array('test','name','description',':Id'=>$_GET['id']); // replace the first 3 with the actual dynamic fields, $_GET['fields'];

It’s a bit of a hard problem I’m guessing. If possible, I would love to forego the white list checking. Any ideas?

Try getting the attribute names from the model and filter the data from $_GET this way:

$model = new myObj(); // your model

$criteria=new CDbCriteria();

$mycriteria = explode(',', $_GET['fields']; // make array of the input

 $mycriteria = array_intersect($mycriteria, array_keys($model->getAttributes())); // Get the attributes from input which exists in the model

$select = implode(',', $criteria); // make comma separated list for input into query

$criteria->select = $select;


Thank you Paul! It seems like a good and cleaner workaround. I will try it and post results later.

I had to reorganize some code, but apparently it worked as expected.


            $allowedFields=array_intersect($this->selectFields,array_keys($this->model->attributes)); //selectFields are already trimmed