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

cast_on_hydrate ignored when columns are specified in Query Builder

Hello everyone, I've run into something quite specific and wondered if someone could take a look and advise if there is a fix?

In my bootstrap I have used ini_set() to set the value of cast_on_hydrate ini_set('phalcon.orm.cast_on_hydrate', 'on'); and I'm using Phalcon 3.4.0 on PHP 7.2.11.

If I use Model::find() style methods, cast_on_hydrate seems to be working fine. This changes when I use Query Builder though. Note that I'm using a multi-module style app with Model Namespacing enabled.

If I use Phalcon's Query Builder to create a simply query:

$di = \Phalcon\Di::getDefault();
$modelsManager = $di->getModelsManager();
$builder = $modelsManager
     ->createBuilder()
     ->from(['Jobs' => 'Jobs:Jobs']);
$results = $builder->getQuery()->execute();
var_dump($results[0]->id);

var_dump displays the result, correctly casted as an integer: int(87)

If I then add some columns into the mix:

// using same getModelsManager() as above
$builder = $modelsManager
     ->createBuilder()
     ->columns(['Jobs.id', 'Jobs.user_id'])
     ->from(['Jobs' => 'Jobs:Jobs']);
// getting results from $builder is same as above example

The output from var_dump is now string(2) "87"

My questions about this are:

  • Is this the expected behaviour, or is this a bug that I should report?
  • Are there any workarounds? e.g. I wondered if I used Phalcon\Mvc\Model\MetaData\Strategy\Annotations whether that would make any difference
  • Can I pass the details of the selected columns to query builder somehow and force it to cast the results of the query in a certain way? I've seen Phalcon\Mvc\Model\Query::setBindTypes() but this did not seem to work (see below)

For the final point here are some examples of what I've tried, which does not seem to work:

// using same $builder as above
$query = $builder->getQuery();
$query->setBindTypes([
     'Jobs.id' => \Phalcon\Db\Column::BIND_PARAM_INT,
     'Jobs:Jobs.id' => \Phalcon\Db\Column::BIND_PARAM_INT,
     'id' => \Phalcon\Db\Column::BIND_PARAM_INT,
]);
$results = $query->execute();
var_dump($results[0]->id); // string(2) "87"

I would really appreciate any suggestions or advice regarding the above. Thanks for your help in advance!

Hi @rich setBindTypes() is to set the type of parameters not "columns types" in results. however, if the result is a \Phalcon\Mvc\Model\Resultset\Simple, the columns should be classified, it is probably a small bug.

Check that or create a new issue on github

Good luck

edited Nov '18

thanks @emiliodeg, I checked and the returned class type is indeed \Phalcon\Mvc\Model\Resultset\Simple.

I'll go ahead and create a new issue on GitHub.

Update: issue raised



938
Accepted
answer
edited Nov '18

Fixed: seems like the db Di Service needed some additional PDO options:

$this->diContainer->setShared('db', new MySQLAdapter(
            [
                'host' => $this->config->database->host,
                'username' => $this->config->database->username,
                'password' => $this->config->database->password,
                'dbname' => $this->config->database->name,
                'options' => [
                    \PDO::ATTR_EMULATE_PREPARES => false,
                    \PDO::ATTR_STRINGIFY_FETCHES => false,
                ],
            ]
        ));

In my case adding just \PDO::ATTR_EMULATE_PREPARES => false did the job.

References: here and my issue on GitHub

Thanks for all the help both on GitHub and in the forum here.