【问题标题】:Issue with Classes, Instances and Objects类、实例和对象的问题
【发布时间】:2015-10-10 22:40:44
【问题描述】:

我对 PHP 还很陌生;但是我认为我对它有很好的掌握,但是我在理解为什么我无法访问我拥有的连接到 DB 类的第二个版本时遇到了问题。

我全局连接到配置脚本中的第一个。

$db = new db(array('login info'));

我使用以下方法在我的控制器中访问它。

public $db;
public function __construct(){
    $this->db = $GLOBALS['db'];
}

然后在我的控制器中,我有一个函数,我可以在其中创建一个新实例以连接到不同的数据库。

$ordersDB = new db(array('login info'));

现在我想使用类似的东西分别访问每个数据库

$this->db->select("SELECT * FROM ada Yada 

$ordersDB->select("SELECT * FROM Yada Yada

但是两者仍在访问第一个数据库。我知道这一点,因为在执行第二个表时我得到一个表不存在错误,它告诉我它正在查询什么数据库。然而,它们的 var_export 表明它们实际上是不同的!我是否完全误解了课程的运作方式,或者我一次只能打开一个数据库?感谢您的帮助。

编辑:这是你要找的吗?

$db = new db(array(connect info));
$controller = new controller();
$controller->connectToSecondDB();

class db {

    public $dbHost;
    public $dbUser;
    public $dbName;
    public $dbPassword;

    public function __construct() {
       $arguments = func_get_args();

       if(!empty($arguments)){
          foreach($arguments[0] as $key => $property){
            if(property_exists($this, $key)){
                $this->{$key} = $property;
            }
           }
       }
    }

  public function connect() {            
        if(!isset(self::$connection)) {       
            self::$connection = new mysqli($this->dbHost, $this->dbUser, $this->dbPassword, $this->dbName);
        }
}

class controller {
   public $db;
   public function __construct(){
      $this->db = $GLOBALS['db'];
   }

   public function connectToSecondDB(){
      $ordersDB = new db(array(connect info));
      $ordersDB->select("SELECT * FROM `customer` WHERE email = 'email@address.com' LIMIT 1")
      $this->db->query("SQL");
   }
}

EDIT 选择查询函数

private function _sel($table, $where="", $order_by="", $limit="", $group_by="",$database = NULL){
        if($database === NULL) {  $database = $this->db; }
        if($limit == 1){ $single = true; }else{ $single = false; }

        //if( is_array($where) ){ $this->_buildWhere(); }
        $where = (strlen($where) > 0) ? "WHERE $where " : $where;       
        $group_by = (strlen($group_by) > 0) ? "GROUP BY $group_by " : $group_by;        
        $order_by = (strlen($order_by) > 0) ? "ORDER BY $order_by " : $order_by;        
        $limit = (strlen($limit) > 0) ? "LIMIT $limit " : $limit ;

        $sql = "SELECT * 
                FROM `$table` 
                $where 
                $group_by 
                $order_by 
                $limit";
        // Debug

//if(INCLUDE_CHECK){ echo "<HR>".$sql."<HR>";   }
        $results = $database->select($sql); 
        if($single && count($results) > 0 ){
            return($results[0]);
        }else{
            return($results);
        }
    }

【问题讨论】:

  • 你能创建并发布一个short, Self Contained, Correct (Compilable), Example 来完整显示问题吗?
  • @VolkerK 这是你要找的吗?
  • 恕我直言,为了找到错误,还缺少很多其他代码(例如 db 的构造函数),请使用 OO 命名约定:类名是以大写开头的连接词(例如 MyClass)
  • 看起来您的 class db 在其构造函数中“隐藏”了 singleton
  • @leonixyz 我已经添加了构造函数。

标签: php mysql class object


【解决方案1】:

一种解决方案是重用您的 $controller 对象。添加query 方法。然后您可以将查询与连接方法分开运行,以便可以重用控制器对象

您需要在整个过程中检查每个步骤。

请注意,我删除了$this-&gt;db-&gt;query("SQL");,因为我不确定它到底做了什么。答案中的概念应该让您开始重新设计您的课程。

更新 根据评论,我将 $db 从超级全局更改并将其传递给控制器​​对象。

$db = new db(array(connect info));
// try passing the $db object so it does not need to be a super global
$controller = new controller($db);
// You can keep your $controller object as a global - I use a session variable for this to reuse it between pages.
$controller->connectToSecondDB();
// run the query separate from the connection so the controller object can be reused
$result = $controller->ordersQuery("SELECT * FROM `customer` WHERE email = 'email@address.com' LIMIT 1")


class db {

    public $dbHost;
    public $dbUser;
    public $dbName;
    public $dbPassword;
    public $connection;

    public function __construct() {
       $arguments = func_get_args();

       if(!empty($arguments)){
          foreach($arguments[0] as $key => $property){
            if(property_exists($this, $key)){
                $this->{$key} = $property;
            }
           }
       }
    }

  public function connect() {            
        if(!isset($this->$connection)) {       
            $this->connection = new mysqli($this->dbHost, $this->dbUser, $this->dbPassword, $this->dbName);
        }
}

class controller() {
   public $db;
   public $ordersDB;    // ADD THIS

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

   public function connectToSecondDB(connect info){
      $ordersDB = new db(array(connect info));
   }

   public function ordersQuery($sql){
      $this->ordersDB->query($sql)
      // Fetch and return you result set here
   }

}

【讨论】:

  • 我注意到你仍然有 "self::$connection = new mysqli($..." 是设计使然吗?这就是我为了让它正常工作而改变的。还有我所有的数据库调用在控制器内部。这意味着我从不执行 $controller->query,因为一旦控制器完成处理,就无需再次查询数据库。这与您提到的效果基本相同吗?跨度>
  • 好收获。我专注于其他变化。我已经更新它以反映。仍然需要更多的改变。例如,$this-&gt;db-&gt;query("SQL"); 应该做什么?
  • 这只是为了表明我正在那里运行查询。我实际上在控制器类中有一个运行所有查询的函数。我已经编辑了主帖以完整地展示这个功能。
  • 好。您应该能够用您的选择替换我的选择并将 db 对象传递给它。祝你好运。
  • 你真的不应该再依赖超全局变量了。将您的数据库实例传递给构造函数。这是一个更好的方法
猜你喜欢
  • 2017-05-29
  • 2014-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多