【问题标题】:Accessing object in models parent访问模型父对象中的对象
【发布时间】:2014-04-20 21:12:43
【问题描述】:

我正在尝试调用我的 Database 类中的一个函数,但我似乎无法正确调用它。

我的模型类调用数据库并将其分配给一个变量:

class Model {

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

    function __destruct() {
        $this->db = NULL;
    }

}

我正在尝试从以下位置调用它:

class User extends Controller {

    function __construct() {
        parent::__construct();
    }

    public function userExists($username) {
        return $this->model->db->select('users', 'id', 'email LIKE ?', array($username));
    }
}

但我不断收到错误:

Fatal error: Call to a member function select() on a non-object in C:\Apache24\htdocs\Manager 2014\controllers\User.php on line 10

我的数据库类是:

class Database extends PDO {

    function __construct($user = 'root', $pass = '', $database = 'xxx', $host = 'localhost') {
        try {
            parent::__construct('mysql:host=' . $host . ';dbname=' . $database, $user, $pass);
            $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
            $this->setAttribute(PDO::ATTR_PERSISTENT, FALSE);
            $this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
            $this->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
            $this->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, FALSE);
            $this->exec("SET NAMES utf8");
        } catch (PDOException $e) {
            Database::handleDbError($e);
        }
    }

    public function select($table, $cols, $where = null, $whereVals = null, $order = null) {
        if ($this->tableExists($table)) {
            $PDOParams = array();
            $SQL = 'SELECT ' . $cols . ' FROM ' . $table;
            if ($where) {
                $SQL .= ' WHERE ' . $where;
            }
            if ($whereVals) {

            }
            if ($order) {
                $SQL .= 'ORDER BY ' . $order;
            }
            return $SQL;
        } else {

        }
    }

    public function tableExists($table) {
        $r = $this->PDO->prepare("SHOW TABLES LIKE ?");
        $r->execute(array($table));
        return $r->rowCount();
    }

}

我做错了什么?


如果我:

print_r(get_class_vars ('UserModel'));

从我得到的用户类:

Array( [db] => )

这对我来说没有意义,因为这是在调用 UserModel 时调用的构造函数中的 Model 中分配的。


我的 Database 类中没有 select(),现在我的主 Model 类中有以下内容:

public function get($primaryKeyId) {
    $table = str_replace('model', '', strtolower(get_called_class()));
    $SQL = "SELECT * FROM $table WHERE id = ?";
    $r = $this->db->prepare($SQL);
    $r->execute(array($primaryKeyId));
    return $r->fetch();
}

【问题讨论】:

    标签: php mysql oop pdo


    【解决方案1】:

    您的实现存在许多基本缺陷。

    1. 首先,去掉select()函数

      • 它非常不安全,允许原始变量进入查询
      • 它非常不灵活,只允许愚蠢的沙盒查询
      • 它使整洁的几乎自然的 SQL 英语变得难以阅读
    2. 其次,不要在每次调用类时都创建新的数据库实例。即使是简单的应用程序也会在连接数如此之多的情况下杀死您的数据库服务器。

      • 将 db 作为参数传递给构造函数
    3. 从您的评论看来,errorhandler 方法不处理任何使它变得邪恶的事情

      • 如果您不知道如何处理错误 - 就让它过去吧。彻底摆脱这个 try/catch 的东西

    【讨论】:

    • 以前我在所有模型中都创建了 get、set、create 和 delete 函数,即使我只需要进行简单的选择。这就是为什么我想出了一个全局选择函数来节省在我的模型中创建大量获取函数的时间。为什么它会不安全(我打算在它使用 PDO 的地方完成它)?
    • 1. PDO 并不是让你的所有 SQL 都化为乌有的魔法咒语。你永远不应该在查询中添加一个变量——只有这样它才会安全。 2. 这是你的原型模型应该包含get、set、create和delete函数。并且 get() 应该与您当前的 select() 不同,只允许从预定义的表名变量中查找主键。
    • 因此,如果它们是在我的主模型类中定义的,我会通过以下方式从 UserModel 中调用 get:$this->get($column, $table, $primaryKeyId); ?
    • @imperium2335 是的,完全正确。这就是extends 的实际用途。但它应该是 $this->get($primaryKeyId);因为模型应该已经知道表名并返回整行而不是单列
    • 但是,如果我不声明要获取哪些列,如果我只需要一列,那么恢复所有内容是否效率不高?
    【解决方案2】:

    模型中的数据库对象需要是公共的,以便可以在 Model 类之外进行访问。

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

    有关公共、受保护和私有之间区别的详细信息,请参阅object visibility

    【讨论】:

    • @wanasten 我认为类上下文中的未声明变量默认为 public 吗?无论如何它都没有用:(
    • documentation 不清楚未声明的类属性是否是公共的,这是我注意到的一件事。你确定你已经包含了包含 Model 类的文件吗?如果您在 Model 类中添加一个测试公共函数,您可以访问该函数吗?
    • 是的,我在 Model 类中创建的任何函数或属性都可以调用。
    【解决方案3】:

    我刚刚完成了 AMP 的自定义构建并且忘记启用 mysql PDO 扩展...这就是 DB 参数为空的原因FACEPALM

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-16
      • 1970-01-01
      • 2021-08-03
      • 2010-09-23
      • 2017-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多