Deprecated: Creation of dynamic property ... is deprecated
I’m seeing this more and more, and I’m not sure what I need to do to stop this warning.
This is my class:
class database {
public $username = "root";
public $password = "pasword";
public $port = 3306;
public function __construct($params = array())
{
foreach ($params as $key => $value)
{
$this->{$key} = $value;
}
}
}
This is how I’m instanacing it.
$db = new database(array(
'database' => 'db_name',
'server' => 'database.internal',
));
Which gives me two messages:
Deprecated: Creation of dynamic property database::$database is deprecated
Deprecated: Creation of dynamic property database::$server is deprecated
7
Answers
So the warnings are coming from the constructor adding dynamic class properties. If you don’t have to pass in those fields dynamically and really, it does seem like you’re overcomplicating something simple then try it like this.
Is there a reason you needed dynamic parameters? You could also do this:
If you add the parameters ahead of time, they’re not dynamic, and you’re just assigning a value to something already existing.
This should work now without any warnings.
An alternative solution, which is specific to this example in that the parameters are quite easy to identify. Databases have common parameters that are referenced.
Using PHP 8 named parameters and Constructor property promotion, allows you to specify all of the possible parameters in the constructor (which is a bit long winded, but great for code completion) and then when creating an instance, the parameter names are fixed…
Then call with
The warning message you are seeing is related to the use of a feature in PHP called "dynamic properties". Dynamic properties allow you to set and get object properties by using variable names, like you are doing in the
__construct
method of your database class.Quick fix:
To fix this warning, you can remove the use of dynamic properties in your code and use a more modern way of setting object properties.
Named arguments:
Alternatively, you can also use the
__set
and__get
magic methods to set and get object properties, like this:This will allow you to use the
$object->property
notation to set and get object properties, without triggering the warning message.You can avoid the need to specify an explicit list of member variables by storing them in a single array, like this:
Then you can instantiate a
database
object with any params you want:Of course, you’ll probably want to document what the expected params are, but at least you’ll be able to pass in anything you want, and be able to use it in the future, without changing the class definition.
The warning is telling you that there is a property you are trying to set which isn’t listed at the top of the class.
When you run this:
It is roughly equivalent to this:
The warning is that there is no line in the class definition saying that
$db->database
or$db->server
exist.For now, they will be dynamically created as untyped public properties, but in future, you will need to declare them explicitly:
In some rare situations, you actually want to say "the properties of this class are whatever I decide to add at run-time"; in that case, you can use the
#[AllowDynamicProperties]
attribute, like this:Adding this just above the class{ will fix it:
#[AllowDynamicProperties]
if you only want the warnings not to be displayed, simply replace this:
for this: