使用在其他类中构建的连接方法并不起作用

时间:2014-08-02 12:58:43

标签: php class methods pdo connection

我最近一直在使用动态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->"它仍然给我一个错误。

1 个答案:

答案 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开放。请改用预备语句。