2016-04-23 61 views
4

我知道PHP會在腳本末尾自動關閉打開的MySQL連接,打開持久連接的唯一可行方法是使用適當的PHP函數;許多問題已經被提出並回答。 我想知道的是利益 - 或不便 - 保持暫時的連接,而不是持續連接

編輯的: 每個PHP用戶會話持久連接
例如,語句如下列:PHP在腳本末尾自動關閉連接

session_start(); 
$connection = new mysqli($host, $user, $pass, $db); 
$_SESSION['connection'] = $connection; 

可能設立跨導航網站由同一用戶在同一會話中執行多個查詢中有用的mysqli的對象的引用。

如果連接在啓動後不久就會被使用,那麼將其作爲進一步查詢的正確選擇將不會是正確的選擇嗎?也許這種方法會產生一個不方便的情況(以及可能存在的安全風險),當多個用戶是一個網站的HTTP請求頁面時,這會使MySQL連接保持活躍狀態​​? 我想知道更多。謝謝。

+1

我也想知道這將如何影響性能和安全性:),upvoted問題 – Webeng

+0

每個請求是PHP一個新的生命週期,它不具有持續性一個類似的狀態你可能會得到其他地方。如果您要爲多個請求/用戶使用相同的連接,那麼您可能會看到競爭條件(首先完成哪些查詢),獲取「最後插入的ID」可能會給您另一個用戶插入的ID等 – JimL

+0

這是不可能的序列化(保存mysqli連接)到會話,所以示例代碼將無法按預期工作。 – drew010

回答

2

連接到MySQL或任何數據庫都有開銷,儘管它通常不是很大。當MySQL服務在另一臺服務器上運行時,或者根據所需的身份驗證方法和init命令,此開銷可能會更大。

更多,MySQL連接可能有相關的緩存。因此,重用連接可能能夠重用這些緩存。

但是在會話中保存資源不起作用。會話數據被序列化並存儲在例如請求之間的文件。這就是爲什麼必須使用持久連接方法的原因。

原因是連接最終是內部類的資源或套接字連接,如果沒有特殊處理,就不能「保存」。試試吧,你會發現你得到一個錯誤(與PDO和庫MySQLi)

mysqli::query(): Couldn't fetch mysqli

我不認爲有任何的方式來獲得特定的會話連接複用,而無需編寫的擴展來實現它。理論上它是可能的,但是理論上你可以實現一個方法來通過會話ID從池中獲取連接。

有很多潛在的缺陷和風險持續DB連接的,但:

  1. 如果您的應用程序創建臨時表,這些表仍會在接下來的運行,因爲它是相同的MySQL會議。

  2. 如果您設置了任何變量(SET SESSION等),它們將被保留。

  3. 取決於如何處理事務,理論上可能持久連接可能有一個正在進行的事務。

  4. 如果應用程序發出任何LOCK命令或使用用戶鎖,那麼這些鎖可以在請求之間保持並且在不知不覺中保存在新的請求中。

  5. 在多租戶(共享)網絡服務器上,另一個進程以某種方式獲取數據庫訪問的風險不應該高於其他進程。

  6. 這可能會導致大量連接長時間打開,從而增加數據庫服務器上的資源使用量。

  7. 您仍然必須期望連接可能會在請求之間丟失。