We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Phalcon handling booleans as ints internally

I am having trouble with phalcon not being able to handle booleans properly. I am trying to create a change log, that contains data that has been changed.

When I use $this->getOldSnapshotData() in model to get old data boolean fields are stored as INTs. And $this->getUpdatedFields() is reporting all booleans as changed always. And as they are typed properties in the model the actual new values are booleans. Is there any way to fix this?

The properties are defined like this in the model. public ?bool $isActive = null; I am not using setters / getters if that matters. I am using Phalcon version 4.

This data is being fed from the database right? MariaDB/MySQL doesn't have a boolean type, it uses 1 & 0. Typically what I do is put some code in afterFetch() to convert from 1/0 to true/false, and some code in beforeSave() to convert vice versa.

This data is being fed from the database right? MariaDB/MySQL doesn't have a boolean type, it uses 1 & 0. Typically what I do is put some code in afterFetch() to convert from 1/0 to true/false, and some code in beforeSave() to convert vice versa.

Yes we are using MariaDB and I know how it works internally. Our problem might be, type conversions thou. We are using our custom validator from another project. It converts types before validating. And the validation is not ran for the snapshots obviously. We might have to rearrange that a bit.

Thanks anyways. I think this might solve our problem. Althou I created a quick workaround for this already. It checks all fields in getUpdatedFields() then validates those changes against the data, so it can filter out these changes where true !== 1 on boolean fields.

Did some testing and it seems afterFetch() is not called for snapshots. So both $this->getOldSnapshotData() and $this->getUpdatedFields() return ints. Are there some other methods that could be used?

edited Apr '20

So you're setting isActive to true (or false), saving the record, then finding isActive is 1 or 0?

It would appear, then, that PDO is converting true/false to 1/0 before executing the save query - and that the snapshots are being created from that converted data, not the data that is being sent to PDO.

I'd maybe file a bug report on GitHub - the developers tend to be more active there than here and they might have more insight.

If you don't want to use getters & setters, then you may be able to overwrite __set(). Phalcon defines its own, but you could write your own that keeps track of changes yourself:

public function __set($name,$newValue){
    $oldValue = $this->{$name};
    if($oldValue !== $newValue){
        $this->changedValues[$name] = $oldValue;
    }

    parent::__set($name,$newValue);
}

Then you could:

$MyObject->isActive = true;
...
$changedFields = $MyObject->changedValues;

I have my own system in place already for getting the changes. I gotta see, if I have time to file a report and maybe they can fix this.