Yii2: PHP 7.4 how to deal with uninitialized typed property

Created on 1 Apr 2020  路  7Comments  路  Source: yiisoft/yii2

What steps will reproduce the problem?

Set a typed property to a model:
public boolean $dummy;

And try to get the attributes:
$model->attributes;

What is the expected result?

No errors.

What do you get instead?

Error : Typed property TestModel::$dummy must not be accessed before initialization
/yii2/framework/base/Model.php:719
/yii2/framework/base/Component.php:139

Additional info

In PHP 7.4 when we try to access a uninitialized typed property it generates an error. "Fatal error: Uncaught Error: Typed property XXX must not be accessed before initialization..."

Keep in mind that uninitialized is not the same as null.

| Q | A
| ---------------- | ---
| Yii version | Don't apply
| PHP version | 7.4
| Operating system | Don't apply

php7 under discussion bug

All 7 comments

Would need to use Reflection and ReflectionProperty::isInitialized in the Model to get around this.
Or you could make your property nullable.

public ?boolean $dummy = null;

Hi @alex-code

We have been discussing this error (@rob006 @bizley ) and we haven't reach an agreement.

Form my point of view, it's not a framework related problem, and as you suggest it's easy to fix by the user.

Reflection is used in other parts of Model so wouldn't be doing anything particularly special if it was used in getAttributes too.
You'd still get an error trying to access a property directly though.

@ricardomm85 Don't you know how php's 7.4 typed properties work? See the manual or read articles about it, for example this
So, fix your code. The variants:

class SomeModel extends Model
{
  // either make the field nullable, as alex-code suggested
  public ?boolean $dummy1 = null;

  // or set the default value
  public boolean $dummy2 = true;

  public boolean $dummy3;

  public boolean $dummy4;

  public boolean $dummy5;

  public boolean $dummy6;

  // or set the value in constructor
  public function __construct(array $config)
  {
    parent::__construct($config);
    $this->dummy3 = true;
  }

  // or set the value in init() method
  public function init()
  {
    $this->dummy4 = true;
  }
}

// or set the value when object is being created
$someModel = new SomeModel(['dummy5' => true]);

// or set the value before using
$someModel->dummy6 = true;

// and then you won't have any problems accessing it:
$attributes = $someModel->attributes;

So, framework has nothing to do with this problem.

@alexgivi totally agree. As, I said before, I also think it's not a framework related issue.

Shall we close this issue?

The discussion should not be about the handling of the uninitialized typed properties because like @alexgivi sarkily mentioned it's already handled. The discussion should be about whether or not to handle this error on validation stage by returning validation error message. But indeed maybe it's too much and we should keep it as it is.

It's programming error, not validation error so I'd prefer not handing it.

Was this page helpful?
0 / 5 - 0 ratings