【问题标题】:Static method calling result of mysql querymysql查询的静态方法调用结果
【发布时间】:2012-10-27 13:02:21
【问题描述】:

我有

class Check
{
    public function __construct()
    {
        $this->db = new Database();
    }

    public function query()
    {
        $login = Session::get("login");
        $sth = $this->db->prepare('SELECT admin FROM accounts WHERE login=:login');
        $sth->execute(array(':login' => $login));
        $result = $sth->fetch(PDO::FETCH_NUM);
        return $result[0];
    }

    public static function admin()
    {
        echo self::query();
    }
}

我在另一个地方有数据库类,有 PDO 连接。

class Database extends PDO
{
    public function __construct()
    {
        parent::__construct('mysql:host=localhost;dbname=name','root','pass');
        $this->query('SET NAMES utf8');
    }
}

所以在 Check::admin() 代码之后我得到错误:

未定义属性:View::$db

为什么?

【问题讨论】:

    标签: php mysql oop


    【解决方案1】:

    您正在使用static 方法,它想要使用instance 变量。

    您的管理方法调用查询方法,查询方法使用db 实例变量。由于您的类未实例化,db 变量不存在。

    我的建议是使管理方法非静态并像这样使用您的代码:

    $mycheck = new Check();
    $mycheck->admin();
    

    或者,如果您使用的是 php 5.4 并且想坚持使用 oneliner:

    (new Check())->admin();
    

    更新

    注意:不要在构造函数中创建db类,而是注入它:

    public function __construct(Database $db)
    {
       $this->db = $db;
    }
    

    【讨论】:

    • 谢谢!但我的任务是使用静态方法。我应该在 mysql 中查询并得到结果:用户是否为管理员。
    • 如果您想通过静态方法访问实例变量,请实例化类:$mycheck = new Check(); $mycheck::admin(); 这是糟糕的编程。如果您正在学习的课程可以教您这一点,请获得退款。
    • 我有自学。感谢您的意见!我只想让调用方法像一个没有实例的静态方法成为可能。更少的代码,你知道的。但是如果你说它的编程很糟糕,我会改变我的代码。
    • 类中的静态是编写过程代码的一种奇特方式。最好以 OOP 方式进行。随着您的前进,您将从中受益匪浅。
    • 是的。我同意你的看法。但是如果我需要经常检查用户怎么办:他是不是管理员?我应该一直创建一个新实例吗?
    【解决方案2】:

    抱歉,这不是您问题的直接答案,但您的代码存在一些问题,因此请花一些时间检查一下,并询问您是否不清楚。

    <?php
    
    class Check {
        protected $_db;
    
        public function __construct(Database $db) {
            $this->_db = $db;
        }
    
        public function query(ISession $sessionData) {
            //WHY IS THE SESSION STATIC?
            //$login = Session::get("login");
            $sth = $this->_db->Connection()->prepare('SELECT admin FROM accounts WHERE login=:login');
            $sth->execute(array(':login' => $sessionData->get("login")));
            $result = $sth->fetch(PDO::FETCH_NUM);
            return $result[0];
        }
    
        public function admin(ISession $sessionData) {
            // REALLY BAD TO ECHO HERE
            echo $this->query($sessionData);
        }
    }
    
    class Database {
    
        private $_name;
        private $_password;
        private $_connStr;
        private $_settings;
    
        private $_pdo;
    
        public function __construct($connstr, $name, $password, array $settings = array()) {
            $this->_name = $name;
            $this->_password = $password;
            $this->_connStr = $connstr;
            $this->_settings = $settings;
        }
    
        public function Connection() {
            if ($this->_pdo == NULL) {
                $this->_pdo = new PDO($this->_connStr, $this->_name, $this->_password);
            }
    
            return $this->_pdo;
        }
    
        /* other fancy methods */
    
        public function Close() {
            $this->_pdo = NULL;
        }
    
        public function __destruct() {
            $this->Close();
        }
    }
    

    我不明白为什么你需要一个 Check 类来处理所有这些,因为如果我是你,我会创建这样的东西:

    $currentSession = Session::GetCurrent();
    $currentSession->User()->IsInRole('admin');
    

    请注意,会话不是静态的,如果我要编写更完整的解决方案,我会避免 Session::GetCurrent() 调用,因为当前会话将是某个类实例中的一个字段(例如 HttpApplication)。

    【讨论】:

    • Session 是静态的,因为我有另一个类 Session ;) admin() 中的 Echo 用于测试。我同意你的观点,它太糟糕了:) 我在另一个文件中的数据库类。只有PDO连接。我手动更改了mysql的用户名、密码和dbname。所以这就是为什么我没有使用不同的私有变量。感谢您的帮助!
    猜你喜欢
    • 2016-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多