Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

how to get int fields as int ?

  var_dump(User::findFirst()->id);

string '1' (length=1)

Is there a way to tell the ORM to keep the original type (int here) ? I was thinking about https://docs.phalconphp.com/en/latest/reference/models-metadata.html that I haven't set but it tells that Memory is the default one.



10.6k

You could maybe typecast in the model? I'm not sure if it will work, but worth a try.

Something like:

    <?php

    use Phalcon\Mvc\Model;
    use Phalcon\Mvc\Model\Message;
    use Phalcon\Validation;
    use Phalcon\Mvc\Model\Validator\Uniqueness;
    use Phalcon\Mvc\Model\Validator\Email;
    use Phalcon\Mvc\Model\Validator\PresenceOf;
    use Phalcon\Mvc\Model\Behavior\SoftDelete;

    class User extends Model {
        public (int) $id;
        public $email;

syntax error, unexpected '(int)' (int) (T_INT_CAST), expecting variable (T_VARIABLE)

it doesn't work for object variables :(

so all the fields coming from the ORM are actually strings ?



10.6k
edited Oct '15

You could try using typecast within a get/set function?


    class User extends Model {
        public $id;
        public $email;

        public function getId() {
            return (int) $this->id;
        }
    }

Yes, that's what I found too, thanks.



42.3k
Accepted
answer

I have a base model which every Model inherits:


class BaseModel extends PhalconModel
{
    public function afterFetch() {
        foreach ($this->getModelsMetaData()->getDataTypes($this) as $field => $type) {
            if (is_null($this->$field)) {
                continue;
            }
            switch ($type) {
                case Column::TYPE_BOOLEAN:
                    $this->$field = ord($this->$field);
                    break;
                case Column::TYPE_BIGINTEGER:
                case Column::TYPE_INTEGER:
                    $this->$field = intval($this->$field);
                    break;
                case Column::TYPE_DECIMAL:
                case Column::TYPE_FLOAT:
                    $this->$field = floatval($this->$field);
                    break;
                case Column::TYPE_DOUBLE:
                    $this->$field = doubleval($this->$field);
                    break;
            }
        }
    }
}
edited Oct '15

Thanks Lajos, that's a good one to handle the most common cases ! Do you know if there is a Column::TYPE_DATE ? (edit : there is : https://docs.phalconphp.com/en/latest/api/Phalcon_Db_Column.html)

edited Oct '15

I don't know about a DateTime object, since this sets the class member and not the returned variable by the getter. If the ORM can save it back to the db there should be no problem with this:

                case Column::TYPE_DATETIME:
                    $this->$field = new DateTime::createFromFormat('Y-m-d H:i:s',$this->$field);
                    break;
                case Column::TYPE_DATE:
                    $this->$field = new DateTime::createFromFormat('Y-m-d',$this->$field);
                    break;

Edit: You might want to use a custom DateTime class and implement a __toString magic method with the correct formatting.

Hi maybe we could make an new feature for models for specify columns types

edited Oct '15

@lajosbencz, yes that might work quite well like that, I'll have a look into it.

@emiliodeg, the column types are extracted from the DB schema, and I've also seen https://docs.phalconphp.com/en/latest/reference/models-metadata.html#annotations-strategy in which you can specify them manually. That might be a great feature to have them auto-casted function of this metadata manager, whatever the sgtrategy is.

Hi there I found a interesting problem. When you use different sintax in model and db tables like fullName in model and full_name in db table the above example are wrong. $field is the model property not the db property. we need use


$sqlField = $this->getModelsMetaData()->getColumnMap($this)[$field]; //this is the real sql field

Good lock

edited Dec '15

you should try the "orm.cast_on_hydrate" ini setup


orm.cast_on_hydrate = 1

or

Model::setup(['castOnHydrate' => true]);

@lajosbencz, Thanks for that.

I turned it into a separate function typeCast(), that's also called on the afterSave() function because as far as I can tell, the afterFetch() function is not called after save and the fields lose their type casting after a savae.