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

TypeError when looping through Resultset\Complex

I'm getting the following error when I try to execute a query that contains a leftJoin and therefore expects the 'right side' to be null in some cases.

Fatal error: Uncaught TypeError: Typed property Tax::$id must be int, null used in [...] Stack trace: #0 [internal function]: Phalcon\Mvc\Model::cloneResultMap(Object(Tax), Array, NULL, 0, false) #1 [internal function]: Phalcon\Mvc\Model\Resultset\Complex->current() #2 [...]

What I did is introduce explicit property types in my Models like so:

class Tax extends \Phalcon\Mvc\Model

     * @var integer
     * @Primary
     * @Identity
     * @Column(column="id", type="integer", length=11, nullable=false)
    protected int $id;


As you can see, the field 'id' cannot be null, among other fields.

What happens is, when I do a leftJoin to Tax table, sometimes the whole object needs to be null (doesn't exist). But instead a Tax object gets created anyway, with all fields set to null - which leads to TypeError being thrown.

The simplified query and loop in question:

$resulSet = DI::getDefault()->getModelsManager()->createBuilder()
            ->from(["Value" => 'Value'])
            ->leftJoin('Tax', 'Value.tax_id = Tax.id', 'Tax')

        foreach ($resultSet as $row) { // error gets thrown on this line for some rows

Is this inteded behaviour? If yes, can it be overcome? Is there another way to do this and still keep the explicit typing in models?


Additional info:

PHP Version 7.4.8

Phalcon Version 4.0.6

edited Aug '20

My guess is this would be intended behaviour. Depending on the rest of the context, I can think of a couple possible solutions:

  1. You could allow your typed property to be null
    protected ?int $id;

    Though that looks like it might break some annotations & documentation

  2. You could change the hydration mode of your query to return an array or a plain (non-model) object.
  3. You might be able to put an @ in front of the foreach. That's dirty though.