De vez en cuando veo preguntas sobre la conexión a la base de datos.
La mayoría de las respuestas no son como las hago yo, o es posible que no las obtenga correctamente. De todas formas; Nunca lo había pensado porque la forma en que lo hago me funciona.
Pero he aquí un pensamiento loco; Quizás estoy haciendo todo mal, y si ese es el caso; Realmente me gustaría saber cómo conectarme correctamente a una base de datos MySQL usando PHP y PDO y hacerla fácilmente accesible.
Así es como lo estoy haciendo:
En primer lugar, aquí está mi estructura de archivos (simplificada) :
public_html/
* index.php
* initialize/
-- load.initialize.php
-- configure.php
-- sessions.php
index.php
En la parte superior, tengo require('initialize/load.initialize.php');
.
load.initialize.php
# site configurations
require('configure.php');
# connect to database
require('root/somewhere/connect.php'); // this file is placed outside of public_html for better security.
# include classes
foreach (glob('assets/classes/*.class.php') as $class_filename){
include($class_filename);
}
# include functions
foreach (glob('assets/functions/*.func.php') as $func_filename){
include($func_filename);
}
# handle sessions
require('sessions.php');
Sé que hay una forma mejor, o más correcta, de incluir clases, pero no recuerdo cuál era. Aún no he tenido tiempo de investigarlo, pero creo que fue algo con autoload
. algo como eso...
configure.php
Aquí básicamente anulo algunas propiedades de php.ini y hago alguna otra configuración global para el sitio
connect.php
He puesto la conexión en una clase para que otras clases puedan extender esta ...
class connect_pdo
{
protected $dbh;
public function __construct()
{
try {
$db_host = ' '; // hostname
$db_name = ' '; // databasename
$db_user = ' '; // username
$user_pw = ' '; // password
$con = new PDO('mysql:host='.$db_host.'; dbname='.$db_name, $db_user, $user_pw);
$con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$con->exec("SET CHARACTER SET utf8"); // return all sql requests as UTF-8
}
catch (PDOException $err) {
echo "harmless error message if the connection fails";
$err->getMessage() . "<br/>";
file_put_contents('PDOErrors.txt',$err, FILE_APPEND); // write some details to an error-log outside public_html
die(); // terminate connection
}
}
public function dbh()
{
return $this->dbh;
}
}
# put database handler into a var for easier access
$con = new connect_pdo();
$con = $con->dbh();
//
Aquí creo que hay margen para una mejora masiva desde que comencé a aprender OOP y a usar PDO en lugar de mysql.
Así que acabo de seguir un par de tutoriales para principiantes y probé cosas diferentes ...
session.php
Además de manejar sesiones regulares, también inicializo algunas clases en una sesión como esta:
if (!isset($_SESSION['sqlQuery'])){
session_start();
$_SESSION['sqlQuery'] = new sqlQuery();
}
De esta manera esta clase está disponible en todo el lugar. Esto podría no ser una buena práctica (?) ...
De todos modos, esto es lo que este enfoque me permite hacer desde todas partes:
echo $_SESSION['sqlQuery']->getAreaName('county',9); // outputs: Aust-Agder (the county name with that id in the database)
Dentro de my sqlQuery
- class , que extends
my connect_pdo
- class , tengo una función pública llamada getAreaName
que maneja la solicitud a mi base de datos.
Bastante ordenado, creo.
Funciona de maravilla.
Así es básicamente como lo estoy haciendo.
Además, siempre que necesito buscar algo de mi base de datos que no está dentro de una clase, simplemente hago algo similar a esto:
$id = 123;
$sql = 'SELECT whatever FROM MyTable WHERE id = :id';
$qry = $con->prepare($sql);
$qry -> bindParam(':id', $id, PDO::PARAM_INT);
$qry -> execute();
$get = $qry->fetch(PDO::FETCH_ASSOC);
Desde que puse la conexión en una variable dentro de connect_pdo.php , solo me he referido a ella y estoy listo para comenzar. Funciona. Obtengo mis resultados esperados ...
Pero independientemente de eso; Realmente agradecería que me dijeran si me voy de aquí. Lo que debería hacer en su lugar, las áreas que podría o debería cambiar para mejorar, etc.
Estoy ansioso por aprender ...
Respuestas:
La meta
Como yo lo veo, su objetivo en este caso es doble:
Solución
Recomendaría usar tanto la función anónima como el patrón de fábrica para tratar con la conexión PDO. Su uso se vería así:
Luego, en un archivo diferente o inferior en el mismo archivo:
La fábrica en sí debería verse así:
De esta manera, le permitiría tener una estructura centralizada, lo que garantiza que la conexión se cree solo cuando sea necesario. También facilitaría mucho el proceso de prueba unitaria y mantenimiento.
En este caso, el proveedor se encontraría en algún lugar de la etapa de arranque. Este enfoque también proporcionaría una ubicación clara donde definir la configuración que utiliza para conectarse a la base de datos.
Tenga en cuenta que este es un ejemplo extremadamente simplificado . También puede beneficiarse de ver los dos videos siguientes:
Además, recomendaría encarecidamente leer un tutorial adecuado sobre el uso de PDO (hay un registro de tutoriales incorrectos en línea).
fuente
mysql_*
a PDO. Luego, puede volver y ver estas soluciones, que están dirigidas a aquellos que ya usan PDO, pero necesitan una forma de compartir la conexión de base de datos entre varias clases.Sugeriría no usar
$_SESSION
para acceder a su conexión de base de datos globalmente.Puede hacer una de las siguientes cosas (en orden de las peores a las mejores prácticas):
$dbh
usandoglobal $dbh
dentro de sus funciones y clasesUse un registro singleton y acceda a eso globalmente, así:
Inyecte el controlador de la base de datos en las clases que lo necesiten, así:
Recomiendo encarecidamente el último. Se lo conoce como inyección de dependencia (DI), inversión de control (IoC) o simplemente el principio de Hollywood (No nos llame, nosotros lo llamaremos).
Sin embargo, es un poco más avanzado y requiere más "cableado" sin marco. Entonces, si la inyección de dependencia es demasiado complicada para usted, use un registro singleton en lugar de un montón de variables globales.
fuente
sqlQuery
clase en sesión ya que se extiendeconnect_pdo
?Recientemente llegué a una respuesta / pregunta similar por mi cuenta. Esto es lo que hice, por si a alguien le interesa:
Para llamarlo solo necesitas modificar esta línea:
Y la sugerencia de tipo si la está usando para (\ Library \ PDO $ DB).
Es realmente similar tanto a la respuesta aceptada como a la suya; sin embargo, tiene una ventaja notable. Considere este código:
Si bien puede parecer un PDO normal (solo cambia por eso
\Library\
), en realidad no inicializa el objeto hasta que llama al primer método, cualquiera que sea. Eso lo hace más optimizado, ya que la creación de objetos PDO es un poco cara. Es una clase transparente, o lo que se llama Fantasma , una forma de Carga diferida . Puede tratar el $ DB como una instancia de PDO normal, pasarlo, realizar las mismas operaciones, etc.fuente
fuente