我最近一直在使用动态PDO连接方法。但是当我开始使用其他类时,我遇到了一些问题。
为什么我不能使用在Server类中构造的方法连接到Admin类中的数据库?
我尝试了很多解决方案。这个对我来说似乎最合乎逻辑......
如何使其工作以便我不必在每个班级中构建连接?
class Server
{
private $hostdb = 'blah';
private $namedb = 'blah';
private $userdb = 'blah';
private $passdb = 'blah';
public static $conn;
public $errorMessage = 'If you read this text, contact web administrator and tell him about your problem.';
public function __construct()
{
$this->connect();
}
public function connect()
{
try {
$this->conn = new PDO("mysql:host=$this->hostdb; dbname=$this->namedb", $this->userdb, $this->passdb, array(PDO::ATTR_PERSISTENT => true));
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->conn->exec("SET CHARACTER SET utf8");
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
}
}
和Admin类:
class Admin extends User
{
function someFunction($table)
{
try {
$sql = "SELECT * FROM $table";
//I want to change this line so that my connection would work
$result = Server::$conn->query($sql);
while ($row = $result->fetch(PDO::FETCH_NUM)) {
//Do something
}
} catch (PDOException $e) {
//Show when debugging
//echo $e->getMessage();
echo Server::errorMessage;
}
}
}
我已经在config.req.php文件中实例化了Server,User和Admin类。
当我改变" Server :: $ conn->" to" static :: $ conn->"它仍然给我一个错误。
答案 0 :(得分:0)
确保在Request中至少有一次实例化Server。否则,永远不会调用connect()
。此外,$this->conn
将创建一个新的公共实例属性。 Static properties need to be set with static::$conn
or self::$conn
因此,请将connect()
方法更改为
public function connect()
{
try {
self::$conn = new PDO("arguments …"));
self::$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$conn->exec("SET CHARACTER SET utf8");
// … shortened for brevity
另外,为什么不使用Dependency Injection?这使得更易于维护和可测试的设计,例如,保留$this->conn
并删除所有静态内容(除了构造函数之外),例如
class Server
{
private $hostdb = 'blah';
private $namedb = 'blah';
private $userdb = 'blah';
private $passdb = 'blah';
private $conn;
public function getConnection()
{
if (!isset($this->conn)) {
$this->connect();
}
return $this->connection;
}
然后是您的Admin类:
class Admin extends User
{
private $server;
public function __construct(Server $server)
{
$this->server = $server;
}
function someFunction($table)
{
try {
$sql = "SELECT * FROM $table";
$result = $this->server->getConnection()->query($sql);
另一方面说明:
$sql = "SELECT * FROM $table"
将字符串插入查询会使您对SQL Injection attacks开放。请改用预备语句。