int values are strings?

I’m doing some output in json and noticed that values that are supposed to be integers (as they are declared in the db and in the rules of the models) are not.

a simple test like: is_int($model->myvalue) lead to TRUE.

if this is not supposed to work I’d like to ask a couple of questions:

  1. am I supposed to open a bug for that?

  2. will this be implemented correctly in 1.1 ?

  3. how have I to cope with that?

speaking of this, what is the right way to do that? I’d do a backcast to int but it would be great if I already know which one should be integers: the rules got that information, but how am I supposed to access that information? is there another way to achieve that?

best regards,

up

noone? really?

Not sure if i understand the problem. But i guess you know about PHP’s “type juggling”, do you? Submitted values will always be strings at first. They are converted to other types depending of the context.

ok, I knew about php loose types (prbly not the right word) and all that you said, this means that I shouldn’t expect an attribute of a model being an “integer” even if the database has this field set as int, isn’t it?

Now comes Json: converting a model to json gives an output where every attribute is set as string (i.e. double quoted), while I would have preferred that integer attributes are outputted as integers not as strings. Simple as that.

Now what is the solution to all this?

  1. using CJSON object? would it take care of my models’ attributes type?

  2. back cast the attributes to int before sending them to json_encode(). To do that I would probably need to access the model’s rules to see which one are integers: is there a way to check it easily?

thanks for anyone who can reply

I came across this issue today. It seems CJSON uses gettype() to determine type when encoding, which is why numeric types are encoded as strings. After a little digging, I decided the easiest solution was to modify getAttributes within CActiveRecord to typecast on my behalf. I’m rather new to Yii so there may be other issues I’m not aware of, but this solution is working for me.

You can find CActiveRecord at yii.db.ar and modify the getAttributes routine as follows.


public function getAttributes($names=true)

{

	$attributes=$this->_attributes;

	foreach($this->getMetaData()->columns as $name=>$column)

	{

		if(property_exists($this,$name))

			$attributes[$name]=$this->$name;

		else if($names===true && !isset($attributes[$name]))

			$attributes[$name]=null;

		// inserted the following to typecast for use with CJSON

		else

			settype($attributes[$name],$column->type);

	}

	if(is_array($names))

	{

		$attrs=array();

		foreach($names as $name)

			$attrs[$name]=isset($attributes[$name])?$attributes[$name]:null;

		return $attrs;

	}

	else

		return $attributes;

}

You should not modify framework files to ease later updates. Instead you could create your own baseclass for you records and override getAttributes() there.


class MyTypeCastRecord extends CActiveRecord {

  public function getAttributes() {

    //...your implementation here

  }

}