close - pdo php pdf
Cómo configurar correctamente una conexión PDO (4)
La meta
Según lo veo, tu objetivo en este caso es doble:
- crear y mantener una conexión única / reutilizable por base de datos
- asegúrese de que la conexión se haya configurado correctamente
Solución
Yo recomendaría utilizar tanto la función anónima como el patrón de fábrica para manejar la conexión PDO. El uso de esto sería así:
$provider = function()
{
$instance = new PDO(''mysql:......;charset=utf8'', ''username'', ''password'');
$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
return $instance;
};
$factory = new StructureFactory( $provider );
Luego en un archivo diferente o más bajo en el mismo archivo:
$something = $factory->create(''Something'');
$foobar = $factory->create(''Foobar'');
La fábrica en sí debería verse más o menos así:
class StructureFactory
{
protected $provider = null;
protected $connection = null;
public function __construct( callable $provider )
{
$this->provider = $provider;
}
public function create( $name)
{
if ( $this->connection === null )
{
$this->connection = call_user_func( $this->provider );
}
return new $name( $this->connection );
}
}
De esta manera, le permitiría tener una estructura centralizada, lo que asegura que la conexión se cree solo cuando sea necesario. También haría mucho más fácil el proceso de prueba y mantenimiento.
El proveedor en este caso se encontraría en algún lugar en la etapa de arranque. Este enfoque también daría una ubicación clara donde definir la configuración que usa para conectarse a la base de datos.
Tenga en cuenta que este es un ejemplo extremadamente simplificado . También podrías beneficiarte viendo dos videos siguientes:
Además, recomiendo leer un tutorial adecuado sobre el uso de PDO (hay un registro de mal tutorial en línea).
De vez en cuando veo preguntas relacionadas con la conexión a la base de datos.
La mayoría de las respuestas no es de la manera en que lo hago, o quizás no obtenga las respuestas correctamente. De todas formas; Nunca lo había pensado porque la forma en que lo hago funciona para mí.
Pero aquí hay un pensamiento loco; Tal vez 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 hacer que sea de fácil acceso.
Así es como lo estoy haciendo:
Primero, aquí está la estructura de mi archivo (despojado) :
public_html/
* index.php
* initialize/
-- load.initialize.php
-- configure.php
-- sessions.php
index.php
En la parte superior, he 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 qué era. Aún no he tenido tiempo de investigarlo, pero creo que fue algo con autoload
. algo como eso...
configure.php
Aquí, básicamente, simplemente anulo algunas propiedades 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í sí creo que hay espacio para la mejora masiva desde que empecé a aprender OOP recientemente, y el uso de PDO en lugar de mysql.
Así que acabo de seguir un par de tutoriales para principiantes y probé cosas diferentes ...
sessions.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 todas partes. Esto podría no ser una buena práctica (?) ...
De todos modos, esto es lo que este enfoque me permite hacer desde cualquier lugar:
echo $_SESSION[''sqlQuery'']->getAreaName(''county'',9); // outputs: Aust-Agder (the county name with that id in the database)
Dentro de mi sqlQuery
- clase , que extends
mi connect_pdo
- clase , tengo una función pública llamada getAreaName
que maneja la solicitud a mi base de datos.
Bastante limpio, creo.
Funciona de maravilla
Entonces, básicamente, así es como lo estoy haciendo.
Además, cada vez que necesito recuperar algo de mi base de datos desde 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);
Como puse la conexión dentro de una variable dentro de connect_pdo.php , solo me he referido a ella y estoy listo para continuar. Funciona. Obtengo los resultados esperados ...
Pero a pesar de eso; Realmente les agradecería si pudieran decirme si estoy lejos de aquí. Lo que debería hacer en su lugar, áreas que podría o debería cambiar para mejorar, etc.
Estoy ansioso por aprender ...
Recientemente llegué a una respuesta / pregunta similar por mi cuenta. Esto es lo que hice, en caso de que alguien esté interesado:
<?php
namespace Library;
// Wrapper for /PDO. It only creates the rather expensive instance when needed.
// Use it exactly as you''d use the normal PDO object, except for the creation.
// In that case simply do "new /Library/PDO($args);" with the normal args
class PDO
{
// The actual instance of PDO
private $db;
public function __construct() {
$this->args = func_get_args();
}
public function __call($method, $args)
{
if (empty($this->db))
{
$Ref = new /ReflectionClass(''/PDO'');
$this->db = $Ref->newInstanceArgs($this->args);
}
return call_user_func_array(array($this->db, $method), $args);
}
}
Para llamarlo, solo necesita modificar esta línea:
$DB = new /Library/PDO(/* normal arguments */);
Y la sugerencia de tipo si la está usando para (/ Library / PDO $ DB).
Es muy similar tanto a la respuesta aceptada como a la tuya; sin embargo, tiene una ventaja notable. Considera este código:
$DB = new /Library/PDO( /* args */ );
$STH = $DB->prepare("SELECT * FROM users WHERE user = ?");
$STH->execute(array(25));
$User = $STH->fetch();
Si bien puede parecer PDO normal (solo cambia /Library/
), en realidad no inicializa el objeto hasta que llame al primer método, cualquiera que sea. Eso lo hace más optimizado, ya que la creación de objetos PDO es un poco caro. Es una clase transparente, o lo que se llama un Ghost , una forma de carga diferida . Puede tratar el $ DB como una instancia PDO normal, pasarla, hacer las mismas operaciones, etc.
Sugeriría que no use $_SESSION
para acceder a su conexión de base de datos de forma global.
Puedes hacer una de algunas cosas (en orden de peor a las mejores prácticas):
- Acceda
$dbh
usandoglobal $dbh
dentro de sus funciones y clases Use un registro singleton y acceda a eso globalmente, de esta manera:
$registry = MyRegistry::getInstance(); $dbh = $registry->getDbh();
Inyecte el manejador de la base de datos en las clases que lo necesitan, así:
class MyClass { public function __construct($dbh) { /* ... */ } }
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, lo llamaremos).
Sin embargo, es un poco más avanzado y requiere más "cableado" sin un marco. Entonces, si la inyección de dependencia es demasiado complicada para usted, use un registro singleton en lugar de un conjunto de variables globales.
$dsn = ''mysql:host=your_host_name;dbname=your_db_name_here''; // define host name and database name
$username = ''you''; // define the username
$pwd=''your_password''; // password
try {
$db = new PDO($dsn, $username, $pwd);
}
catch (PDOException $e) {
$error_message = $e->getMessage();
echo "this is displayed because an error was found";
exit();
}
o lea en http://ask.hcig.co.za/?p=179