ActiveRecord to JSON?

How do you display JSON data with activerecord… Right now I just write the json myself in a view because I don’t need all data in a activerecord object so cannot use json_encode direct. Is there any better (easier) way?


echo json_encode($model->getAttributes(array('id','name','email')));

If for one record :) But what if there are many? Is there anyway to avoid doing a loop to create new arrays and then encoding them?

I found CJSON in the API but not really any example how to use… and how to use with related records :)

I utilise PHP’s powerful array functions whenever possible. Check array_map(). You can do something like:


$models=Bla::model()->findAll();

$data=array_map(create_function('$m','return $m->getAttributes(array(\'id\',\'name\'));'),$models);

echo json_encode($data);

CJSON is able to do the job:


$models = Post::model()->findAll();

CJSON::encode($models);


$model = Post::model()->find();

CJSON::encode($model);

CJSON doesn’t filter out attributes…

thanks mike. :)

I have a problem with




echo json_encode($model->getAttributes(array('id','name','email')));



the id field is encoded like string

{"id":"123", …

instead of

{"id":123, …

how to correct this behaviour?

You will have to cast your numeric model values to integers.

Alternative, if you use php >= 5.3.3 you can




echo json_encode($model->getAttributes(array('id','name','email')), JSON_NUMERIC_CHECK);




echo json_encode($model->getAttributes(array('id','name','email')), JSON_NUMERIC_CHECK);

seams to be very bad solution

if i have varchar field with value "023" it is encoded like number 23 and decoded back as "23"

what do you mean cast numeric values to integers? example maybe…

see php type casting:




$number = (int)$somethingElse;// cast to int

$number = (float)$somethingElse; // cast to float

$string = (string)$somethingElse; // cast to string

$array = (array)$somethingElse;//cast to array

$object = (object)$somethingElse;// cast to object



PHP’s JSON_NUMERIC_CHECK is not a bad solution at all, it depends of your use case for it.

Hello, i added this function to CActiveRecord class:




public function findAllJson($condition='',$params=array())

	{

		Yii::trace(get_class($this).'.findAll()','system.db.ar.CActiveRecord');

		$criteria=$this->getCommandBuilder()->createCriteria($condition,$params);

		$data = $this->query($criteria,true);

                $final = array();

                foreach ($data as $value) {

                    $aux = array();

                    foreach ($value as $row => $inf) {

                        if ($inf != NULL)

                            $array[$row] = $inf;

                    }

                    $final[]=$array;

                }

                return json_encode($final);

	}



regards!

you could also get the active record as array and then json_encode it

$model = ActiveRecordModel::find()->asArray()->all();

$json = json_encode($model);