Nay mình chia sẻ với mọi người cách chúng ta sử dụng Singleton Design Patterns trong PHP. Để tạo connect đến Database. Cách mọi người cũng hiểu về Singleton rồi.
Github: https://github.com/skipperhoa/Design-Patterns
Singleton Design Patterns
Đảm bảo một thể hiện duy nhất: Singleton đảm bảo rằng chỉ có một thể hiện của lớp được tạo ra, giúp tiết kiệm bộ nhớ và tài nguyên hệ thống.
Truy cập toàn cục: Singleton cung cấp một phương thức để truy cập đối tượng duy nhất này. Phương thức này thường được gọi là getInstance().
Tính bảo mật: Lớp Singleton thường hạn chế việc tạo đối tượng trực tiếp (thông qua constructor private), để ngăn chặn việc tạo nhiều đối tượng từ bên ngoài.
Ứng dụng: Singleton thường được sử dụng trong các tình huống cần một kết nối duy nhất, ví dụ như kết nối cơ sở dữ liệu, quản lý cấu hình toàn cục hoặc log.
<?php class Singleton { protected static self|null $instance = null; // Chặn khởi tạo trực tiếp final private function __construct() {} // Chặn nhân bản đối tượng final protected function __clone() {} // Chặn unserialize đối tượng final protected function __wakeup() {} // Phương thức lấy instance duy nhất public static function getInstance(): static { if (static::$instance === null) { echo "Đang khởi tạo instance...\n"; static::$instance = new static; } echo "Instance tạo thành công!\n"; return static::$instance; } }
Trong lớp DatabaseConnect chúng ta sẽ kế thừa lớp Singleton
<?php /* Design Patterns - Singleton : Singleton đảm bảo một lớp đặt bản một instance và cung cấp một điểm truy cập toàn cách đặt bản đó. */ require_once 'Singleton.php'; class DatabaseConnection extends Singleton { private $host = 'db'; private $db_name = 'db_hoanguyencoder'; private $username = 'hoanguyencoder'; private $password = '12345678'; private $pdo = null; // Kết nối đến MySQL private function connect() { if ($this->pdo === null) { try { $this->pdo = new PDO("mysql:host={$this->host};dbname={$this->db_name}", $this->username, $this->password); $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo "Đang kết nối tới cơ sở dữ liệu...\n"; echo "Kết nối thành công!\n"; } catch (PDOException $e) { die("Lỗi kết nối: " . $e->getMessage()); } } } // Phương thức để lấy kết nối hiện tại public function getConnection() { // Đảm bảo kết nối được khởi tạo $this->connect(); return $this->pdo; } } ?>
Chúng ta có thể sử dụng như sau :
<?php require_once 'DatabaseConnection.php'; // Sử dụng Singleton $db1 = DatabaseConnection::getInstance(); $db2 = DatabaseConnection::getInstance(); // Kiểm tra $db1 và $db2 có cùng instance var_dump($db1 === $db2); // true $conn = $db1->getConnection(); echo "Show data users \n"; $result = $conn->query("SELECT * FROM User"); while ($row = $result->fetch(PDO::FETCH_ASSOC)) { print_r($row); }
Bên trên là một cách giúp ta chỉ tạo ra một instance , có nghĩa là chỉ tạo ra một kết nối trong ứng dụng
Nếu bạn không thích cách viết trên, bạn có thể sử dụng cách sau;
<?php class Database { // Biến tĩnh để lưu giữ instance duy nhất của class Database private static $instance = null; private $pdo; private $host = 'db'; private $db_name = 'db_hoanguyencoder'; private $username = 'hoanguyencoder'; private $password = '12345678'; private function __construct() { $charset = 'utf8mb4'; $dsn = "mysql:host=$this->host;dbname=$this->db_name;charset=$charset"; $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]; try { $this->pdo = new PDO($dsn, $this->username, $this->password, $options); } catch (\PDOException $e) { throw new Exception($e->getMessage()); } } public static function getInstance() { if (self::$instance === null) { // Tạo một instance duy nhất nếu chưa có self::$instance = new Database(); } // Trả về đối tượng PDO đã được tạo return self::$instance->pdo; } } // Usage: $db1 = Database::getInstance(); $db2 = Database::getInstance(); var_dump($db1 === $db2); // true // Output: The same instance echo "\n"; echo $db1 === $db2 ? 'Giống nhau' : 'Khác nhau';