4

也许这是一个愚蠢的问题,但我对 PDO 很陌生并且很困惑。是否可以在一个函数中实例化 PDO 对象(打开与服务器/数据库的连接),然后在另一个函数中关闭相同的连接?是否需要将函数传递给对象才能关闭它?我想这样做,这样我就可以创建一个无处不在的站点范围的函数,我可以调用它来启动连接、执行非通用 sql,然后用另一个站点范围的函数关闭它。我怎样才能做到这一点?我需要将对象作为参数传递给这些函数吗?

4

3 回答 3

12

是的,这是可能的。我建议使用启动与 MySQL 的连接的构造函数和使它无效的析构函数。这样,您就不必在每次想要打开和关闭连接时手动调用该函数。每当调用对象的新实例时,连接就会打开,并且当没有对该对象的进一步引用时,连接将被取消。

它可能看起来像这样:

    private $l; //MySQL Connection

    //Called automatically upon initiation
    function __construct() {
        try {
            $this->l = new PDO("mysql:host=".MYSQL_HOST.";dbname=".MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD); //Initiates connection
            $this->l->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); // Sets error mode
        } catch (PDOException $e) {
            file_put_contents("log/dberror.log", "Date: " . date('M j Y - G:i:s') . " ---- Error: " . $e->getMessage().PHP_EOL, FILE_APPEND);
            die($e->getMessage()); // Log and display error in the event that there is an issue connecting
        } 
    }

    //Called automatically when there are no further references to object
    function __destruct() {
        try {
            $this->l = null; //Closes connection
        } catch (PDOException $e) {
            file_put_contents("log/dberror.log", "Date: " . date('M j Y - G:i:s') . " ---- Error: " . $e->getMessage().PHP_EOL, FILE_APPEND);
            die($e->getMessage());
        }
    }

你可能会发现这个关于构造函数和析构函数的参考很有用:http: //php.net/manual/en/language.oop5.decon.php

于 2012-11-21T16:41:51.220 回答
2

据我了解,您只需连接到数据库一次,而不必为每个函数打开连接。数据库连接将自动关闭,但您可以通过将空值分配给 PDO 对象来手动关闭它。

当您实例化 PDO 对象时建立连接。

$dbh = new PDO("mysql:host=$hostname;dbname=mysql", $username, $password);

并在脚本末尾或您为其分配空值时自动关闭

$dbh = null;

有用的指南在这里

于 2012-11-21T16:35:10.033 回答
1

好吧,例如,您可以在 php 中有一个主要的工作类,它在其类中实例化一个 DBRoutines 对象。对象引用作为受保护的 var/object 驻留在 worker 中,但对 DB 类中的所有 DB 例程进行 -> 调用。并在其生命周期的后期调用 DB::Close 函数。这么确定。

索引.php:

class Xcrud
{   protected static $firephp;
    protected static $_instance = array();

...

...

$db = Xcrud_db::get_instance($this->connection);

$db->query("SELECT `{$field}` FROM `{$this->table}` WHERE `{$this->primary}` = " . $db->escape($this->primary_key) . " LIMIT 1");

xcrud_db.php:

class Xcrud_db
{   protected static $firephp;
private static $_instance = array();
private $connect;
private $result;
private $dbhost;
private $dbuser;
private $dbpass;
private $dbname;
private $dbencoding;

public static function get_instance($params = false)
{   some code
}
private function __construct($dbuser, $dbpass, $dbname, $dbhost, $dbencoding)
{
    $this->firephp = FirePHP::getInstance(true);
    $this->firephp->setEnabled(true);
    //$this->firephp->log('xcrud_db.php:__construct');
    if (strpos($dbhost, ':') !== false)
    {
        list($host, $port) = explode(':', $dbhost, 2);
        $this->connect = mysqli_connect($host, $dbuser, $dbpass, $dbname, $port);
    } else
        $this->connect = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);
    if (!$this->connect)
        $this->error('Connection error. Can not connect to database');
    $this->connect->set_charset(str_replace('-', '', $dbencoding));
    if ($this->connect->error)
        $this->error($this->connect->error);
}
public function query($query = '')
{
    $this->firephp->log('xcrud_db.php:query='.$query);
    $this->result = $this->connect->query($query); //echo $query;
    if ($this->connect->error)
        $this->error($this->connect->error);
    return $this->connect->affected_rows;
}
etc
于 2012-11-21T16:22:36.627 回答