У меня есть класс базы данных, который использует PDO. Вот пример этого:
class db { private $host; private $username; private $password; private $con; private $pdo; public function __construct( $database = "dnname" ) { $this->host = "localhost"; $this->username = "username"; $this->password = "pass"; $conStr = "host={$this->host};dbname={$database}"; try { $this->pdo = new PDO( "mysql:$conStr", $this->username, $this->password ); $this->pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); } catch( PDOException $e ) { echo "error ". $e->getMessage(); } } public function fetch_single_row($sql, $data) { if( $data !== null ) $data = array_values( $data ); // Incase it's an associative array $sel = $this->pdo->prepare( $sql ); $sel->execute( $data ); $sel->setFetchMode( PDO::FETCH_OBJ ); $obj = $sel->fetch(); return $obj; }
Я хотел бы использовать этот класс и его функции (он имеет больше, чем я включил) внутри других классов.
Я пробовал много разных вещей, но единственное, что работает до сих пор, – это запуск нового экземпляра db в каждом новом классе, который, по моему мнению, является плохой практикой . Например:
class cms { function cms(){ $this->db = new db(); } function is_admin($id) { if($this->db->fetch_single_row("SELECT id FROM user WHERE id = ? LIMIT 1", array($id))){ return true; } else { return false; } }
в моем index.php, я включаю эти классы и использую их:
include("db.class.php"); include("cms.class.php"); $cms = new cms(); if($cms->is_admin($id)){ //code here }
вinclude("db.class.php"); include("cms.class.php"); $cms = new cms(); if($cms->is_admin($id)){ //code here }
вinclude("db.class.php"); include("cms.class.php"); $cms = new cms(); if($cms->is_admin($id)){ //code here }
Каков правильный способ сделать это?
Взгляните на шаблон дизайна Singleton, он отлично подходит для класса DB
Раньше я использовал такой класс довольно долгое время
abstract class DB { protected static $instance; protected $db; protected static $host = 'host'; protected static $user = 'user'; protected static $pass = 'pass'; protected static $database; public static function getInstance() { if (!isset(self::$instance)) self::$instance = new static(); return self::$instance; } protected function __construct() { $this->db = new PDO(sprintf('mysql:host=%s;dbname=%s', static::$host, static::$database), static::$user, static::$pass); $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } public static function db() { return static::getInstance()->db; } public function fetch_single_row($sql, $data) { if( $data !== null ) $data = array_values( $data ); // Incase it's an associative array $sel = self::db()->prepare( $sql ); $sel->execute( $data ); $sel->setFetchMode( PDO::FETCH_OBJ ); $obj = $sel->fetch(); return $obj; } }
Затем я бы расширил этот класс для каждой базы данных, с которой мне нужно было бы подключиться
class Main extends DB { protected static $database = 'db'; }
Затем вы можете использовать класс, подобный этому
$db = Main::getInstance(); $obj = $db->fetch_single_row($sql, $data);