Я хочу иметь возможность создавать классы, которые расширяют класс MySQLi для выполнения всех своих SQL-запросов.
$mysql = new mysqli('localhost', 'root', 'password', 'database') or die('error connecting to the database');
Я не знаю, как это сделать без глобализации объекта $ mysql для использования в моих других методах или классах.
class Blog { public function comment() { global $mysql; //rest here } }
Любая помощь будет оценена по достоинству.
Благодарю.
Мое предложение – создать класс Singleton DataAccess, создать экземпляр этого класса в глобальном файле конфигурации и вызвать его в своем классе Blog, например $query = DataAccess::query("SELECT * FROM blog WHERE id = ".$id)
.
Посмотрите на шаблон Singleton, это довольно легко понять шаблон разработки. Идеально подходит для этой ситуации.
Класс DataAccess может иметь несколько методов, таких как query
, fetchAssoc
, numRows
, checkUniqueValue
, transactionStart
, transactionCommit
, transactionRollback
т. Д. Эти функции также могут быть настроены как интерфейс, который реализуется классом DataAccess. Таким образом, вы можете легко расширить свой класс DataAccess для нескольких систем управления базами данных.
Выше в значительной степени описывается модель DataAccess.
Я работал над чем-то подобным. Я рад этому классу singleton, который инкапсулирует логин базы данных.
<?php class db extends mysqli { protected static $instance; protected static $options = array(); private function __construct() { $o = self::$options; // turn of error reporting mysqli_report(MYSQLI_REPORT_OFF); // connect to database @parent::__construct(isset($o['host']) ? $o['host'] : 'localhost', isset($o['user']) ? $o['user'] : 'root', isset($o['pass']) ? $o['pass'] : '', isset($o['dbname']) ? $o['dbname'] : 'world', isset($o['port']) ? $o['port'] : 3306, isset($o['sock']) ? $o['sock'] : false ); // check if a connection established if( mysqli_connect_errno() ) { throw new exception(mysqli_connect_error(), mysqli_connect_errno()); } } public static function getInstance() { if( !self::$instance ) { self::$instance = new self(); } return self::$instance; } public static function setOptions( array $opt ) { self::$options = array_merge(self::$options, $opt); } public function query($query) { if( !$this->real_query($query) ) { throw new exception( $this->error, $this->errno ); } $result = new mysqli_result($this); return $result; } public function prepare($query) { $stmt = new mysqli_stmt($this, $query); return $stmt; } }
Для использования вы можете иметь что-то вроде этого:
<?php require "db.class.php"; $sql = db::getInstance(); $result = $sql->query("select * from city"); /* Fetch the results of the query */ while( $row = $result->fetch_assoc() ){ printf("%s (%s)\n", $row['Name'], $row['Population']); } ?>
Вы можете использовать ключевое слово extends PHP только для любого другого класса:
class Blog extends mysqli { public function __construct($host, $user, $password, $database) { parent::__construct($host, $user, $password, $database); } public function someOtherMethod() { } } $blog = new Blog('localhost', 'root', 'password', 'database') or die('Cannot connect!');
или лучше использовать агрегацию объектов вместо наследования:
class Blog { private $db; public function __construct($host, $user, $password, $database) { $this->db = new mysqli($host, $user, $password, $database); } public function someOtherMethod() { return $this->db->query("SELECT * FROM blah_balh"); } }
Мой стандартный метод состоит в том, чтобы сделать одноэлементный класс, который действует как доступ к базе данных, и базовый класс, на который наследуется все, требующее такого доступа.
Так:
class Base { protected $db; function __construct(){ $this->db= MyDBSingleton::get_link(); //any other "global" vars you might want } } class myClass extends Base { function __construct($var) { parent::__construct();// runs Base constructor $this->init($var); } function init($id) { $id=(int) $id; $this->db->query("SELECT * FROM mytable WHERE id=$id"); //etc. } }
Взгляните на PDO , которые генерируют исключения для вас, если вы не получите запрос. Он широко используется и тестируется, поэтому у вас не должно возникать проблемы с поиском существующих решений во время его использования.
Чтобы ввести его в свой класс в блоге:
class Blog { private $_db; public function __construct(PDO $db) { $this->_db = $db } public function comment() { return $this->_db->query(/*something*/); } }