8

我在理解这一点时遇到了一些问题。我想开始重写一些旧的 MySQL 函数代码 PDO。它的设置方式是包含此行的外部文件(除其他外):

// db.php file   

$DB = new dbConnect(SERVER,DB,USER,PASSWORD,3306);

function my_autoloader($class)
{
    require_once ($_SERVER['DOCUMENT_ROOT']."/includes/".'class.' . $class . '.php' );
}

spl_autoload_register('my_autoloader');

这将创建与我的数据库的连接。这包含在我页面的最顶部,并且还会加载我的所有课程。现在,如果我想使用 PDO 创建一个新连接,我会执行以下操作:

$conn = new PDO('mysql:host='.SERVER.';dbname='.DB.';charset=utf8',USER, PASSWORD);

但是,我不能将这行代码放在单独的文件中并从类中调用 PDO,如下所示:

require_once 'db.php';
class info
{

    protected $ID;

    public function __construct($id)
    {
        $this->ID = $id; // 
    }

    public function getName()
    {
        $query = "SELECT * FROM job";
        $q = $conn->query($query);
        $data = $q->fetch(PDO::FETCH_ASSOC);
            //do something with $data

    }
}

这是否意味着我必须通过如下聚合在构造函数中建立连接?

require_once 'db.php';
class info
{
    protected $ID;
    protected $pdo;

    public function __construct($id)
    {
        $this->ID = $id; // 
        $this->pdo = new PDO('mysql:host='.SERVER.';dbname='.DB.';charset=utf8',USER, PASSWORD);
    }

    public function getName()
    {
        $query = "SELECT * FROM job";
        $q = $this->pdo->query($query);
        $data = $q->fetch(PDO::FETCH_ASSOC);
        // do something
    }
}

还是有另一种我不知道的方法。尝试重新编写我所有的课程以纳入这一点似乎很乏味。

4

3 回答 3

3

与其在构造函​​数中创建数据库连接,不如让它成为一个依赖项:

public function __construct(PDO $db, $id)
{
    $this->pdo = $db;
    $this->ID = $id;
}

要使用它,您将执行以下操作:

// $db = new PDO('mysql:host='.SERVER.';dbname='.DB.';charset=utf8',USER, PASSWORD);
$info = new info($db, '123');
echo $info->getName();

这种方法的主要优点是您不再有任何配置存储在您的类中。此外,您也可以传递任何实现PDO的内容,从而使用模拟数据库进行单元测试。

于 2013-05-30T03:29:01.677 回答
0

这是我的第一次尝试:

class database extends PDO {

        protected static $instance;

        protected function __construct(){}

        public static function getInstance()
        {
            if(empty(self::$instance))
            {
                 $db_info = array(
                                "db_host" => SERVER,
                                "db_port" => PORT,
                                "db_user" => USER,
                                "db_pass" => PASSWORD,
                                "db_name" => DB);

                 self::$instance = new Database("mysql:host=".$db_info['db_host'].';port='.$db_info['db_port'].';dbname='.$db_info['db_name'], $db_info['db_user'], $db_info['db_pass']);

             }
             return self::$instance;
        }
}

class info
{
    protected $ID;
    protected $pdo;

    public function __construct($id)
    {
        $this->ID = $id; // 
        $this->pdo = database::getInstance();
    }

    public function getName()
    {
        $query = "SELECT * FROM job";
        $q = $this->pdo->query($query);
        $data = $q->fetch(PDO::FETCH_ASSOC);
        // do something
    }
}

我不完全确定这是否正确,因为我目前没有办法对此进行测试。这会被认为是正确的吗?

于 2013-05-30T03:04:54.180 回答
0

创建与数据库的连接时,您应该在单例类中执行此操作。您只想打开一个到数据库的连接。例如:

public class database
{
    static $instance;

    public static function getInstance()
    {
          if($self::$instance == null)
          {
                $self::$instance = new PDO(); // string value here.
          }
          return $instance;
    }
}

然后,您可以从类中的任何位置调用该database::getInstance()方法,而无需不断重写连接代码。

PS:我知道这个单例不是线程安全的。我只是想向 OP 强调这个概念。

于 2013-05-29T19:24:37.927 回答