0

I’m having a hard time with PHP 8.2’s dynamic properties deprecation. I’m looking here for a permanent solution that will be compatible with PHP 9.0, so adding the #[AllowDynamicProperties] attribute is not a solution for me.

Here’s my problem. I used to have, for example, the following class:

class planet {
    function __construct($id, $a, $m, $i, $e, $π) {
        $this->a = $a;
        $this->e = $e;
        $this->i = $i;
        $this->id = $id;
        $this->m = $m;
        $this->n = .9856076686 / ($a * sqrt($a));
        $this->π = $π;
    }
}

Then I would create each planet with the following array:

$pl = [
    new planet("Mercury", .38709831, 3.3011e23, 7.004986, .20563, 77.456119),
    new planet("Venus", .723332982, 4.8675e24, 3.394662, .006772, 131.563703)
];

and so on.

If I try this now, of course I get the now-(in)famous notification: Deprecated: Creation of dynamic property planet::$a is deprecated

So my question is the following: How can I keep creating my planets from an array? It seems to be possible to create single objects with instructions such as $Mercury = new StdClass(); $Mercury->a = .38709831; but this would end up in long code for nothing, I find.

Is there a faster, more efficient way?

I googled and googled, but found nothing that even remotely helps.

2 Answers2

3

You need to make your properties class properties rather than having them dynamic. There is no way around this if you want to keep using your class going forward:

Way 1

class planet {
    public $id; 
    public $e;
    public $a;
    public $m;
    public $i;
    public $π;
    public $n;
    
    function __construct($id, $a, $m, $i, $e, $π) {
        $this->a = $a;
        $this->e = $e;
        $this->i = $i;
        $this->id = $id;
        $this->m = $m;
        $this->n = .9856076686 / ($a * sqrt($a));
        $this->π = $π;
    }
}

Way 2:

class planet {
    public $n; 
    function __construct(public $id, public $a, public $m, public $i, public $e, public $π) {
        $this->n = .9856076686 / ($a * sqrt($a));
    }
}

You can alternatively mark your classes with the AllowDynamicProperties though I would not recommend this.

#[\AllowDynamicProperties]
class planet {
    function __construct($id, $a, $m, $i, $e, $π) {
        $this->a = $a;
        $this->e = $e;
        $this->i = $i;
        $this->id = $id;
        $this->m = $m;
        $this->n = .9856076686 / ($a * sqrt($a));
        $this->π = $π;
    }
}

As far as I know using dynamic properties after you've marked the class with the attribute is still going to be allowed in PHP 9+.

The way you call new to construct the class or how you use the classes will not change after you've implemented one of these solutions.

apokryfos
  • 38,771
  • 9
  • 70
  • 114
1

As you are using PHP8, use Constructor promotion:

public $n;

function __construct(public $id, public $a, public $m, public $i,
                     public $e, public $π) {
  $this->n = .9856076686 / ($this->a * sqrt($this->a));
}

The $n must be declared explicitly as it is not c'tor argument. Also, consider typehinting your properties and arguments.

BTW: Using π as variable name is not a good idea. Use pi instead.

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141