2012-11-21 69 views
4

也許這是一個愚蠢的問題,但我對PDO很陌生並且很困惑。是否有可能在一個函數中實例化PDO對象(打開到服務器/ db的連接),然後在另一個函數中關閉同一個連接?函數是否需要傳遞該對象才能關閉它?我想這樣做,所以我可以創建一個無處不在的站點範圍的函數,我可以調用它來啓動一個連接,執行非泛型sql,然後用另一個站點範圍的函數關閉它。我怎樣才能做到這一點?我是否需要將對象作爲參數傳遞給這些函數?PHP PDO連接和關閉不同功能的連接

回答

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

1

好吧,你可以例如有一個主要的工人類在PHP中實例化一個DBRoutines對象在它的類。對象引用駐留在worker中的受保護的var/object中,但是會調用DB類中的所有DB例程。並在其生命週期的稍後調用DB :: Close函數。那麼確定。

的index.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 
1

從我的理解,你只需要連接數據庫一次,不要'不得不爲每個功能打開一個連接。數據庫連接將自動關閉,但可以通過將空值分配給PDO對象手動關閉它。

當您實例化PDO對象時進行連接。

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

,並在腳本結束時自動關閉,或者當您爲它分配一個空值

$dbh = null; 

有益的指導here