今天,我在PHP中发现了一些意外行为。 我正在尝试一个设置类,其中还包括数据库连接信息。 该类看起来像这样:
class Config
{
static $dbHost = 'localhost';
static $dbName = 'name';
static $dbUser = 'user';
static $dbPass = 'pass';
}
在“服务定位器”中,我配置了一个在需要时创建PDO连接的功能。 代码如下:
$this->configService('db', function (ServiceLocator $context) {
return new \PDO(
'mysql:host=' . Config::$dbHost . ';dbname=' . Config::$dbName . ';charset=utf8',
Config::$dbUser,
Config::$dbPass
);
});
然后我想:如果发生错误,堆栈跟踪可能会暴露config类的内容。因此,在设置数据库连接后,我将取消设置密码:
$this->configService('db', function (ServiceLocator $context) {
$password = Config::$dbPass;
Config::$dbPass = '';
return new \PDO(
'mysql:host=' . Config::$dbHost . ';dbname=' . Config::$dbName . ';charset=utf8',
Config::$dbUser,
$password
);
});
但是这不起作用,当PDO尝试连接时密码将为空。 我做了一些测试,看来PHP一直在使用静态变量的后期绑定。
所以我的问题是:这是怎么回事?在PDO需要它时,PHP是否会设置$ password变量(和Config :: $ dbPass ===”)?
编辑:PHP v7.0.23
答案 0 :(得分:0)
Alexandre Painchaud暗示该代码可能会运行两次。是的,确实如此。
路由器两次包括ServiceLocator:(
这与后期绑定无关。
答案 1 :(得分:0)
不是清除密码,而是使用getter从类中获取价值?基本堆栈跟踪不应显示类的私有属性。
<?php
final class Config
{
private $dbHost = 'localhost';
private $dbName = 'name';
private $dbUser = 'user';
private $dbPass = 'pass';
public function getPassword(): string
{
return $this->dbPass;
}
}
var_dump((new Config())->getPassword());