Why
我們已經可以透過 composer 這個相依函式庫管理軟體來快速的使用資料庫連接物件了,為什麼要重新調整這個連接資料庫的功能呢?
因為實務上,我們發現常常一次網頁請求要建立好幾個跟資料庫的連線,這會佔用很多的系統資源,如果瞬間連線數一衝高,伺服器就會開始裝死,導致所有顧客都無法下單,服務終止,那就真的糗了。
我們要避免這種情況的話,就要保持一個請求只有一次連線,不管使用多少次資料庫資源。這樣的優化無形中,會降低伺服器的負擔,出狀況的機率也可以降低很多。
How
那要怎麼弄呢?
首先,我們先做幾個專案上的優化,把必要參數抽出來寫成弄成 config 資料夾
裡面放一些固定的參數,我們可以學著靜態 Class 的方式來製作
config/MySQL.php
<?php
class MySQL {
const ADDRESS = "localhost";
const USERNAME = "root";
const PASSWORD = "root";
const DATABASE = "game";
}
新建立一個檔案,專門來維持只會一個靜態資料庫物件
libraries/Database.php
<?php
/**
* 使用單例模式的資料庫連接方式,無論使用多少次都是使用同一個連線
*/
<?php
/**
* 使用單例模式的資料庫連接方式,無論使用多少次都是使用同一個連線
*/
class Database {
private static $instance;
private function __construct() {
// 使用 private 建構子避免在外面被意外地初始化
}
private static function getInstance() {
if (!isset(self::$instance)) {
self::$instance = new DatabaseAccessObject(
MySQL::ADDRESS,
MySQL::USERNAME,
MySQL::PASSWORD,
MySQL::DATABASE
);
}
}
public static function get() {
self::getInstance();
if (isset(self::$instance)) {
return self::$instance;
} else {
return NULL;
}
}
public static function unlinkDAO() {
if (isset(self::$instance)) {
self::$instance = null; // 會自動執行解構子 close link
}
}
}
記得要設定 composer 才能直接使用哦
修改 composer.json
{
"name": "jarvis/game",
"authors": [
{
"name": "Jarvis",
"email": "endless640c@gmail.com"
}
],
"require": {
"monolog/monolog": "^1.23"
},
"autoload": {
"classmap": [
"libraries",
"config"
]
}
}
開啟終端機後跳到專案目錄下再下 composer 指令
cd /Application/XAMPP/htdocs/game
composer dump
那在程式碼裡要怎麼使用呢?直接呼叫即可:
$db = Database::get();
What
有沒有注意到 static 這個詞一直冒出來,這是靜態的意思
他可以不需要先 new 實作成物件就可以直接以 class name 後面接 :: 即可使用
如果是變數可以直接 ::變數名,但是如果是 function 函數的話 記得還是要加小括號 ::函數名()
這樣取得 DatabaseAccessObject 的話,無論取幾次都只有一次連線,因為每次取都會檢查是否連線物件已存在,不存在才會建立連線,否則就用同一個連線就好,這樣一來就達到我們的需求:每次來自瀏覽器的請求,都只會跟資料庫建立一個連線。不會因為專案越來老,開始堆積連線數量。
附上參考資料:
https://rongli.gitbooks.io/design-pattern/content/chapter5.html
https://en.wikipedia.org/wiki/Singleton_pattern