De vez em quando, vejo perguntas relacionadas à conexão com o banco de dados.
A maioria das respostas não é como eu faço, ou posso simplesmente não obter as respostas corretamente. De qualquer forma; Nunca pensei nisso porque a maneira como faço funciona para mim.
Mas aqui está um pensamento maluco; Talvez eu esteja fazendo tudo errado, e se for o caso; Eu realmente gostaria de saber como conectar corretamente a um banco de dados MySQL usando PHP e PDO e torná-lo facilmente acessível.
É assim que estou fazendo:
Em primeiro lugar, aqui está minha estrutura de arquivo (reduzida) :
public_html/
* index.php
* initialize/
-- load.initialize.php
-- configure.php
-- sessions.php
index.php
No topo, eu tenho 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');
Sei que existe uma maneira melhor, ou mais correta, de incluir aulas, mas não consigo lembrar qual era. Não tive tempo para investigar ainda, mas acho que era algo com autoload
. algo parecido...
configure.php
Aqui eu basicamente substituo algumas propriedades do php.ini e faço alguma outra configuração global para o site
connect.php
Eu coloquei a conexão em uma classe para que outras classes possam estender 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();
//
Aqui, eu acredito que há espaço para melhorias massivas desde que comecei recentemente a aprender OOP e usar PDO em vez de mysql.
Então, eu apenas segui alguns tutoriais para iniciantes e experimentei coisas diferentes ...
sessões.php
Além de lidar com sessões regulares, também inicializo algumas classes em uma sessão como esta:
if (!isset($_SESSION['sqlQuery'])){
session_start();
$_SESSION['sqlQuery'] = new sqlQuery();
}
Dessa forma, essa aula está disponível em todos os lugares. Isso pode não ser uma boa prática (?) ...
De qualquer forma, é isso que essa abordagem me permite fazer de qualquer lugar:
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 , tenho uma função pública chamada getAreaName
que trata da solicitação para meu banco de dados.
Muito legal, eu acho.
Funciona como um encanto
Então é basicamente assim que estou fazendo.
Além disso, sempre que preciso buscar algo do meu banco de dados que não esteja dentro de uma classe, simplesmente faço algo semelhante a isto:
$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 coloquei a conexão em uma variável dentro de connect_pdo.php , acabei de me referir a ela e estou pronto para continuar. Funciona. Recebo os resultados esperados ...
Mas, independentemente disso; Eu realmente apreciaria se vocês pudessem me dizer se estou longe daqui. O que devo fazer em vez disso, áreas que posso ou devo mudar para melhoria etc ...
Estou ansioso para aprender ...
Respostas:
O objetivo
A meu ver, seu objetivo neste caso é duplo:
Solução
Eu recomendaria usar a função anônima e o padrão de fábrica para lidar com a conexão PDO. O uso seria assim:
Em seguida, em um arquivo diferente ou inferior no mesmo arquivo:
A própria fábrica deve ser parecida com isto:
Dessa forma, você teria uma estrutura centralizada, o que garante que a conexão seja criada apenas quando necessária. Também tornaria o processo de teste de unidade e manutenção muito mais fácil.
O provedor, neste caso, seria encontrado em algum lugar no estágio de bootstrap. Essa abordagem também forneceria um local claro onde definir a configuração que você usa para se conectar ao banco de dados.
Lembre-se de que este é um exemplo extremamente simplificado . Você também pode se beneficiar assistindo aos dois vídeos a seguir:
Além disso, eu recomendo fortemente a leitura de um tutorial adequado sobre o uso de PDO (há um registro de tutoriais ruins online).
fonte
mysql_*
para PDO. Então você pode voltar e olhar para esta solução, que é voltada para aqueles que já usam PDO, mas precisam de uma forma de compartilhar a conexão do banco de dados entre várias classes.Eu sugeriria não usar
$_SESSION
para acessar sua conexão DB globalmente.Você pode fazer algumas coisas (da pior para as práticas recomendadas):
$dbh
usandoglobal $dbh
dentro de suas funções e classesUse um registro singleton e acesse-o globalmente, assim:
Injete o manipulador de banco de dados nas classes que precisam dele, assim:
Eu recomendo o último. É conhecido como injeção de dependência (DI), inversão de controle (IoC) ou simplesmente o princípio de Hollywood (não ligue para nós, nós ligaremos para você).
No entanto, é um pouco mais avançado e requer mais "fiação" sem uma estrutura. Portanto, se a injeção de dependência for muito complicada para você, use um registro singleton em vez de um monte de variáveis globais.
fonte
sqlQuery
-class em sessão, pois ela estendeconnect_pdo
?Recentemente, cheguei a uma resposta / pergunta semelhante por conta própria. Isso é o que eu fiz, caso alguém se interesse:
Para chamá-lo, você só precisa modificar esta linha:
E a sugestão de tipo se você estiver usando para (\ Library \ PDO $ DB).
É muito semelhante à resposta aceita e à sua; no entanto, tem uma vantagem notável. Considere este código:
Embora possa parecer PDO normal (ele muda
\Library\
apenas por isso ), ele na verdade não inicializa o objeto até que você chame o primeiro método, seja ele qual for. Isso o torna mais otimizado, uma vez que a criação do objeto PDO é um pouco cara. É uma classe transparente, ou o que é chamado de Ghost , uma forma de Lazy Loading . Você pode tratar o $ DB como uma instância normal do PDO, passando-o adiante, fazendo as mesmas operações, etc.fonte
fonte