【问题标题】:Using connection method constructed in other class doesn't work使用在其他类中构造的连接方法不起作用
【发布时间】:2014-09-25 13:04:50
【问题描述】:

我最近一直在玩弄动态 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->”更改为“static::$conn->”时,它仍然给了我一个错误。

【问题讨论】:

    标签: php class methods pdo connection


    【解决方案1】:

    确保您在请求中至少实例化了一次服务器。否则,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;
        }
    

    然后是你的管理员类:

    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。请改用准备好的语句。

    【讨论】:

    • 这太棒了。非常感谢。 :)
    猜你喜欢
    • 2016-01-06
    • 1970-01-01
    • 2019-12-30
    • 2019-11-29
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 2011-10-22
    相关资源
    最近更新 更多