La base de datos PHP OOP se conecta

Acabo de empezar a aprender el concepto de progtwigción orientada a objetos y he escrito esta clase con funciones.

Funciona bien, pero me interesa saber si he hecho esto correctamente …

Aquí está mi código:

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 "
    "; echo "
  • ".$username."
  • "; echo "
"; } } 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();

Utilice PDO o MySQLi ya que es más seguro y las funciones de mysql_ * están en desuso como se indicó anteriormente. He proporcionado algún código genérico usando PDO para ayudarlo con esa nueva empresa. Como se afirma en los comentarios, no debería hacer eco de los datos si está buscando un diseño orientado a objetos, lo que debe hacer es después de realizar la consulta, devolver las filas que ha extraído y, a partir de ahí, usar algo como un bucle Foreach para mostrar sus datos. ¡Hacer su clase de base de datos de esta manera también asegurará que las conexiones de bases de datos múltiples no estén abiertas a la vez! Tenga en cuenta que este código es solo para que usted haga referencia, y debe probarse antes de usarlo en producción o cualquier cosa en vivo.

config.php:

  

database.class.php:

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

index.php:

 getData(); ?> 

La respuesta de Sieu Phan está bien, pero en realidad no garantiza que solo tenga una conexión abierta (¿ config.php archivo config.php varias veces crearía conexiones múltiples).

Es posible mejorar la forma en que se conecta a las bases de datos usando contenedores de inyección automática y de dependency injection. Esta es una forma de utilizar Auryn para conectarse a su base de datos, mientras que se asegura de que solo haya una conexión abierta y no tenga que solicitar manualmente los archivos en su aplicación.

Cubriré solo PDO y Auryn aquí. Existen otros contenedores de dependency injection y, en particular, la extensión mysqli para conectarse a la base de datos, pero el contenido debería ayudarlo a utilizar otro contenedor si así lo desea.

La clase de base de datos

Tener una clase de base de datos es superfluo. La clase \PDO ya proporciona todos los métodos necesarios para consultar la base de datos. Tener una clase de base de datos te hace repetir todas las funciones que ya proporciona, y de hecho limita tus acciones (o te hace crear muchas funciones) cuando quieres, por ejemplo, usar múltiples estilos diferentes de búsqueda dependiendo de tus necesidades en un método específico.

Inyección de dependencia

Si aún no lo hizo, lea sobre la dependency injection . El punto es que cuando una clase necesita acceder a la base de datos, no debería tener que molestarse en construir el objeto \PDO , debería construirse con él:

 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(); } } 

Tenga en cuenta que paso directamente el objeto \PDO , no una clase contenedora. De esa manera, siempre tengo acceso a todas sus capacidades, no solo a un subconjunto de funciones definidas por el usuario.

Envase de dependency injection

Un contenedor de dependency injection ayuda a construir sus clases, proporcionándoles los objetos que necesitan y ofreciéndole gran flexibilidad sobre cómo construir realmente esos objetos. Aquí solo me enfocaré en configurar y compartir un objeto \PDO mediante el uso de Auryn.

Supongo que has instalado la clase Auryn requerida, la forma más fácil es usar compositor . Esto está fuera del scope de esta respuesta, existen múltiples recursos sobre cómo usarlo.

  • Crea el inyector

     $injector = new \Auryn\Injector(); 
  • Definir los parámetros de la clase \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, ], ]); 

    Puede escribir los parámetros de configuración directamente aquí, o puede obtenerlos de un archivo de configuración. Me gusta tener un archivo config.ini y usar parse_ini_file() para obtener mis opciones de configuración, ya que puedo cambiar fácilmente las bases de datos editando un archivo de configuración.

  • Compartir el objeto \PDO

     $injector->share("PDO"); 

    Esta parte es realmente importante. Estas líneas hacen que el inyector proporcione el mismo objeto \PDO cada vez que se le encargue la construcción de una clase que necesita una conexión. Tenga en cuenta que el orden de las líneas no es importante, puede compartir la clase antes de definirla, solo asegúrese de crear su base de datos que necesite clases después de escribir ambas líneas.

  • Crea tus objetos

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

    Eso es. El inyector creará su objeto asignador, creando el objeto \PDO si aún no lo ha sido, pasando la instancia existente si lo tiene.

Autoloading

Suponiendo que haya utilizado el compositor, puede hacer uso de su fantástico autocargador. De lo contrario, también puede rodar su propio autocargador .

El punto aquí es dejar de require() en todas partes en su código, especialmente si tiene jerarquías de clases complejas, que debe tener en un solo sistema de clase que cumpla con la responsabilidad .

Terminando

Con esta configuración, ahora puede usar el objeto \PDO en sus clases, al tiempo que se garantiza que solo habrá una instancia por solicitud, sin la necesidad de requerir archivos en todas partes, y sin utilizar un antipatrón de singleton.

 $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->[email protected]_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); } } 
 ![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","[email protected]"); if($Conn) { echo "Database Connect"; } else { echo "Database Connect Failed."; } mysql_close($Conn); ?>] 

1