2013-08-16 195 views
81

與MySQLi相比,PDO只是一個相當簡單的問題。PDO關閉連接

用的MySQLi,收你可以做連接:

$this->connection->close(); 

但是與PDO它規定您使用打開連接:

$this->connection = new PDO(); 

,但關閉的連接,然後將其設置爲null

$this->connection = null; 

這是正確的,這將實際上釋放PDO連接? (我知道它的確如此設置爲null。)我的意思是MySQLi必須調用一個函數(close)來關閉連接。 PDO與= null一樣容易斷開?或者是否有關閉連接的功能?

+11

我問是我不知道,如果我是正確關閉連接的原因。但不是真的只是吸引人 –

+0

你真的需要關閉你的連接嗎? –

+0

「需要多長時間」多久? –

回答

98

根據文檔你是正確的(http://php.net/manual/en/pdo.connections.php):

連接保持積極爲PDO對象的壽命。若要 關閉連接,您需要銷燬對象,方法是確保 的所有其餘引用都被刪除 - 您可以通過將 NULL分配給保存對象的變量來執行此操作。如果你不明確這樣做 ,當你的 腳本結束時,PHP將自動關閉連接。

請注意,如果您將PDO對象初始化爲持久連接,它將不會自動關閉連接。

+3

如果我有一個沒有結束的過程呢?例如WebSocket的。有沒有辦法不使用持久連接? –

+0

請注意,網絡呃逆可能會使您斷開連接。 –

+0

對於長時間運行的腳本中的持久連接,您可以故意(或意外)連接因超時(例如,my.ini)或多種其他原因而中斷連接。在連接或運行查詢時,請捕獲任何錯誤,如果它是「MySQL已消失」,請嘗試再次連接或再次運行查詢。 –

22
$conn=new PDO("mysql:host=$host;dbname=$dbname",$user,$pass); 
    // If this is your connection then you have to assign null 
    // to your connection variable as follows: 
$conn=null; 
    // By this way you can close connection in PDO. 
+8

恕我直言,我認爲這是一個非常糟糕的模式,特別是當開發人員可能會存儲幾個副本的pdo參考。 $ a = new PDO(...); $ b = $ a; $ a = null; 在那裏,你的PDO對象將永遠保持打開狀態(在守護進程的php程序中)。 當PDO參考遍歷函數和對象屬性時,尤其如此,並且您從不肯定將它們全部清零。 – Gabriel

+16

PDO應該有一個 - > close()方法。 – Gabriel

+2

不喜歡PDO的另一個原因。 –

0

我創建了一個派生類,它有一個更自我記錄的指令而不是「$ conn = null;」。

class CMyPDO extends PDO { 
    public function __construct($dsn, $username = null, $password = null, array $options = null) { 
     parent::__construct($dsn, $username, $password, $options); 
    } 

    static function getNewConnection() { 
     $conn=null; 
     try { 
      $conn = new CMyPDO("mysql:host=$host;dbname=$dbname",$user,$pass); 
     } 
     catch (PDOException $exc) { 
      echo $exc->getMessage(); 
     } 
     return $conn; 
    } 

    static function closeConnection(&$conn) { 
     $conn=null; 
    } 
} 

所以,我可以打電話給我之間的代碼:

$conn=CMyPDO::getNewConnection(); 
// my code 
CMyPDO::closeConnection($conn); 
+0

你可以使CMyPDO :: __構造()方法私人和使用單身模式.. –

+0

是的,這是可能的。如果您一次使用多個數據庫,則還需要通過另一種方法分配連接信息。差別很小,只是你有更長的指令來調用實例方法。 – Fil

+0

@AdityaHajare你不能在子類中創建一個超類私有的公共方法。 – nickdnk