Подключение базы данных PHP OOP

Я только начал изучать концепцию объектно-ориентированного программирования, и я написал этот класс с функциями.

Он отлично работает, но мне интересно узнать, правильно ли я это сделал …

Вот мой код:

class Database{ const DB_HOSTNAME = 'localhost'; const DB_USERNAME = 'root'; const DB_PASSWORD = 'password'; const DB_NAME = 'shop'; protected $_db_connect; protected $_sql; protected $_result; protected $_row; function db_connect(){ $this->_db_connect = mysql_connect(self::DB_HOSTNAME,self::DB_USERNAME,self::DB_PASSWORD) or die(mysql_error()); } function slect_db(){ mysql_select_db(self::DB_NAME) or die(mysql_error()); } function sql(){ $this->_sql = 'SELECT * FROM users'; } function query(){ $this->_result = mysql_query($this->_sql); } function fetch_array(){ while($this->_row = mysql_fetch_array($this->_result)){ $username = $this->_row['user_USERNAME']; echo "<ul>"; echo "<li>".$username."</li>"; echo "</ul>"; } } function db_close(){ mysql_close($this->_db_connect); } } $database = new Database(); $database->db_connect(); $database->slect_db(); $database->sql(); $database->query(); $database->fetch_array(); $database->db_close(); 

Пожалуйста, используйте PDO или MySQLi, поскольку он более безопасен, а функции mysql_ * устарели, как указано выше, я предоставил некоторый общий код, используя PDO, чтобы помочь вам в этом новом предприятии. Как указано в комментариях, вы действительно не должны эхом отдавать данные, если вы ищете объектно-ориентированный дизайн, то, что вы должны делать, это после выполнения запроса, возврата строк, которые вы извлекли, и оттуда использовать что-то такой как цикл foreach, чтобы затем отображать ваши данные. Выполнение этого класса базы данных также гарантирует, что сразу несколько соединений с базой данных не будут открыты! Обратите внимание, что этот код предназначен для вас только для ссылки, и его следует тестировать перед использованием в производстве или в любом другом месте.

config.php:

 <?php //Enter your database connection details here. $host = 'localhost'; //HOST NAME. $db_name = 'databasename'; //Database Name $db_username = 'root'; //Database Username $db_password = ''; //Database Password try { $pdo = new PDO('mysql:host='. $host .';dbname='.$db_name, $db_username, $db_password); } catch (PDOException $e) { exit('Error Connecting To DataBase'); } ?> 

database.class.php:

 <?php class database { function __construct($pdo) { $this->pdo = $pdo; } function getData() { $query = $this->pdo->prepare('SELECT * FROM database'); $query->execute(); return $query->fetchAll(); } } ?> 

index.php:

 <?php require_once 'config.php'; require_once 'database.class.php'; $db = new database($pdo); $rows = $db->getData(); ?> 

Ответ Sieu Phan в порядке, но на самом деле он действительно не гарантирует, что вы только открыли одно соединение (вы бы включили файл config.php несколько раз, чтобы создать несколько подключений).

Можно улучшить способ подключения к базам данных с помощью контейнеров для автоматической загрузки и загрузки зависимостей. Вот способ использования Auryn для подключения к вашей базе данных, при этом убедитесь, что открыто только одно соединение и не требуется вручную запрашивать файлы в вашем приложении.

Здесь я расскажу только о PDO и Auryn. Существуют другие контейнеры для инъекций зависимостей, и в частности расширение mysqli для подключения к базе данных, но содержимое должно помочь вам использовать другой контейнер, если вы хотите это сделать.

Класс базы данных

Наличие класса базы данных является излишним. Класс \PDO уже предоставляет все необходимые методы для запроса к базе данных. Наличие класса базы данных позволяет фактически повторить все функции, которые он уже предоставляет, и фактически ограничивает ваши действия (или создает множество функций), когда вы хотите, например, использовать несколько разных стилей выборки в зависимости от ваших потребностей в определенном методе.

Внедрение зависимости

Если вы еще этого не сделали, прочитайте об инъекции зависимостей . Дело в том, что, когда класс должен получить доступ к базе данных, ему не нужно беспокоиться о создании объекта \PDO , он должен быть построен с ним:

 class Mapper { private $pdo; public function __construct(\PDO $pdo) { $this->pdo = $pdo; } public function createFromId($id) { $stmt = $this->pdo->prepare("SELECT name FROM foo WHERE id=:id"); $stmt->execute([ ":id" => $id, ]); return $stmt->fetchObject(); } } 

Обратите внимание, что я напрямую \PDO объект \PDO , а не класс-оболочку. Таким образом, у меня всегда есть доступ ко всем его возможностям, а не только к подмножеству пользовательских функций.

Контейнер для инъекций зависимостей

Контейнер инъекций зависимостей помогает создавать ваши классы, предоставляя им нужные им объекты и предоставляя вам большую гибкость в том, как реально создавать эти объекты. Здесь я остановлюсь только на настройке и совместном использовании объекта \PDO с помощью Auryn.

Я предполагаю, что вы установили необходимый класс Auryn, тем проще использовать композитор . Это выходит за рамки этого ответа, есть несколько ресурсов о том, как его использовать.

  • Создать инжектор

     $injector = new \Auryn\Injector(); 
  • Определить параметры класса \PDO

     $injector->define("PDO", [ ":dsn" => "mysql:host=localhost;charset=utf8;dbname=dbname", ":username" => "user", ":passwd" => "passwd", ":options" => [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ], ]); 

    Вы можете прямо здесь написать параметры конфигурации или получить их из файла конфигурации. Мне нравится иметь файл config.ini и использовать parse_ini_file() для получения моих параметров конфигурации, так как я могу легко переключать базы данных, редактируя файл конфигурации.

  • Поделитесь объектом \PDO

     $injector->share("PDO"); 

    Эта часть действительно важна. Эти строки заставляют инжектор давать тот же объект \PDO каждый раз, когда ему поручается построить класс, которому требуется соединение. Обратите внимание, что порядок строк не важен, вы можете поделиться классом перед его определением, только убедитесь, что вы создали базу данных, требующую классов после написания обеих этих строк.

  • Создайте свои объекты

     $mapper = $injector->make("Mapper"); 

    Вот и все. Инжектор создаст ваш объект mapper, создав объект \PDO если он еще не был, передав существующий экземпляр, если он есть.

Автозагрузка

Предполагая, что вы использовали композитор, вы можете использовать его отличный автозагрузчик. В противном случае вы также можете запустить свой автозагрузчик .

Дело здесь в том, чтобы перестать require() везде в вашем коде, особенно если у вас сложная иерархия классов, которую вы должны иметь в единой системе, совместимой с ответственностью .

Завершение

С помощью этой настройки теперь вы можете использовать объект \PDO в своих классах, при этом гарантируется, что для каждого запроса будет только один экземпляр, без необходимости требовать файлы повсюду и без использования singleton anti-pattern.

 $database = new Connection(); class Connection { function __construct() { switch($_SERVER['DOCUMENT_ROOT']) { case 'path': $this->host = 'hostname'; $this->user = 'username'; $this->passwd = 'password'; $this->database = 'dbname'; break; default : $this->host = 'localhost'; $this->user = 'root'; $this->passwd = 'root'; $this->database = 'dbname'; break; } $this->clink = @mysql_connect($this->host,$this->user,$this->passwd); @mysql_select_db($this->database,$this->clink); } } 

$ objConn = new mysqlconnect (); $ Conn = $ objConn-> setobjConnect ("localhost", "root", "P @ ssw0rd");

 class Database{ var $last_query; //Saved result of the last query made var $last_result; //Results of the last query made var $func_call; //A textual description of the last query/get_row/get_var call var $link; //database link var $lastquery; //last query var $result; //query result // Connect to MySQL database function database() { $this->link=mysql_connect(DB_HOST, DB_USER, DB_PASS) or die('Server connexion not possible.'); //Set All Charsets to UTF8 mysql_query("SET character_set_results=utf8 , character_set_client=utf8 , character_set_connection=utf8 , character_set_database=utf8 , character_set_server=utf8"); mysql_select_db(DB_NAME) or die('Database connection not possible.'); } /** Query the database. * @param $query The query. * @return The result of the query into $lastquery, to use with fetchNextObject(). */ function query( $query ){ $this->lastquery=$query; $this->result=@mysql_query( $query, $this->link ); return $this->result; } /** Do the same as query() but do not return nor store result. * Should be used for INSERT, UPDATE, DELETE... * @param $query The query. * @param $debug If true, it output the query and the resulting table. */ function execute($query) { @mysql_query($query); } /** Convenient method for mysql_fetch_object(). * @param $result The ressource returned by query(). * @return An ARRAY representing a data row. */ function fetchArray($result){ if ($result == NULL) $result = $this->result; if ($result == NULL || mysql_num_rows($result) < 1) return NULL; else return mysql_fetch_assoc($result); } /** Close the connecion with the database server. * It's usually unneeded since PHP do it automatically at script end. */ function close() { mysql_close($this->link); } /** Get the number of rows of a query. * @param $result The ressource returned by query(). If NULL, the last result returned by query() will be used. * @return The number of rows of the query (0 or more). */ function numRows($result = NULL) { if ($result == NULL) return @mysql_num_rows($this->result); else return mysql_num_rows($result); } } 
 ![<?php class mysqlconnect{ private $server=null;private $user=null;private $password=null;private $objConnect=null; function setobjConnect($s,$u,$p){ $this->server = $s; $this->user = $u; $this->password = $p; return $this->objConnect = mysql_connect($this->server,$this->user,$this->password); } } $objConn = new mysqlconnect(); $Conn = $objConn->setobjConnect("localhost","root","P@ssw0rd"); if($Conn) { echo "Database Connect"; } else { echo "Database Connect Failed."; } mysql_close($Conn); ?>] 

1