PHP警告已弃用:不推荐创建动态属性

fhity93d  于 2022-12-26  发布在  PHP
关注(0)|答案(5)|浏览(416)
Deprecated: Creation of dynamic property ... is deprecated

我越来越多地看到这种情况,我不知道我需要做什么来阻止这种警告。
这是我的课

class database {

    public $username = "root";
    public $password = "pasword";
    public $port = 3306;

    public function __construct($params = array())
    {

        foreach ($params as $key => $value)
        {
            $this->{$key} = $value;
        }
    }
}

我是这样示例化的。

$db = new database(array(
    'database' => 'db_name',
    'server' => 'database.internal',
));

这给了我两个信息:

Deprecated: Creation of dynamic property database::$database is deprecated 

Deprecated: Creation of dynamic property database::$server is deprecated
hfwmuf9z

hfwmuf9z1#

所以警告来自于构造函数添加动态类属性,如果你不需要动态地传入那些字段,看起来你确实把一些简单的东西复杂化了,那么试试这样。

class database {

    public $username = "root";
    public $password = "pasword";
    public $port = 3306;
    public $database = 'db_name';
    public $server = 'database.internal';
}

$db = new database();

是否有需要动态参数的原因?您也可以这样做:

class database {

    public $username = "root";
    public $password = "pasword";
    public $port = 3306;
    public $database;
    public $server;

    public function __construct($params = array())
    {

        foreach ($params as $key => $value)
        {
            $this->{$key} = $value;
        }
    }
}

如果提前添加参数,它们就不是动态的,只是给已经存在的东西赋值。
现在应该可以工作了,没有任何警告。

$db = new database(array(
    'database' => 'db_name',
    'server' => 'database.internal',
));
gg0vcinb

gg0vcinb2#

该警告是告诉您有一个您正在尝试设置的属性没有列在类的顶部
当您运行此命令时:

class database {

    public $username = "root";
    public $password = "pasword";
    public $port = 3306;

    public function __construct($params = array())
    {
        foreach ($params as $key => $value)
        {
            $this->{$key} = $value;
        }
    }
}

$db = new database(array(
    'database' => 'db_name',
    'server' => 'database.internal',
));

它大致相当于:

class database {

    public $username = "root";
    public $password = "pasword";
    public $port = 3306;
}

$db = new database;
$db->database = 'db_name';
$db->server = 'database.internal';

警告是类定义中没有一行表示$db->database$db->server存在。
现在,它们将被动态创建为非类型化公共属性,但是将来,您需要显式地声明它们:

class database {
    public $database;
    public $server;
    public $username = "root";
    public $password = "pasword";
    public $port = 3306;

    public function __construct($params = array())
    {
        foreach ($params as $key => $value)
        {
            $this->{$key} = $value;
        }
    }
}

$db = new database(array(
    'database' => 'db_name',
    'server' => 'database.internal',
));

在一些罕见的情况下,您实际上想要说“该类的属性是我决定在运行时添加的任何内容”;在这种情况下,可以使用#[AllowDynamicProperties]属性,如下所示:

#[AllowDynamicProperties]
class objectWithWhateverPropertiesIWant {
    public function __construct($params = array())
    {
        foreach ($params as $key => $value)
        {
            $this->{$key} = $value;
        }
    }
}
wpx232ag

wpx232ag3#

另一种解决方案,它是特定于这个例子的,因为参数很容易识别。数据库有被引用的公共参数。
使用PHP 8命名参数和Constructor属性提升,允许您在构造函数中指定所有可能的参数(这有点冗长,但对代码完成很有帮助),然后在创建示例时,参数名称是固定的。

class database
{
    public function __construct(
        private string $database = '',
        private string $server = '',
        private string $port = '',
        private string $user = '',
        private string $password = ''
    ) {
    }
}

然后打电话给

$db = new database(
    database: 'db_name',
    server: 'database.internal',
);
xn1cxnb4

xn1cxnb44#

通过将成员变量存储在单个数组中,可以避免指定成员变量的显式列表,如下所示:

class database {
    public $data;

    public function __construct($params = array())
    {
        foreach ($params as $key => $value)
        {
            $this->data[$key] = $value;
        }
    }
}

然后,您可以使用所需的任何参数示例化database对象:

$db = new database(array(
    'database' => 'db_name',
    'server' => 'database.internal',
    'foo' => 'bar', // etc.
));

当然,您可能希望记录所需的参数是什么,但至少可以传入任何您想要的参数,并且可以在将来使用它,而无需更改类定义。

6ss1mwsb

6ss1mwsb5#

您看到的警告消息与PHP中名为"dynamic properties"的特性的使用有关。动态属性允许您通过使用变量名来设置和获取对象属性,就像您在数据库类的__construct方法中所做的那样。
快速解决方案:

public function __construct(array $params)
{
    $this->username = $params['username'] ?? null;
    $this->password = $params['password'] ?? null;
    $this->port = $params['port'] ?? null;
}

若要修复此警告,可以在代码中删除动态属性的使用,并使用更现代的方法设置对象属性。
命名参数:

class database
{
    public function __construct(
        public string $username,
        public string $password,
        public int $port,
    ) {}
}

$db = new database(
    username: 'root',
    password: 'password',
    port: 3306,
);

或者,您也可以使用__set__get魔术方法来设置和获取对象属性,如下所示:

public function __set($key, $value)
{
    $this->$key = $value;
}

public function __get($key)
{
    return $this->$key;
}

这将允许您使用$object->property表示法来设置和获取对象属性,而不会触发警告消息。

相关问题