Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá pessoal, fiz uma classe para conexão com uso de mysqli e gostaria que vocês analisassem para ver se possui algum erro ou se quiserem dar alguma dica para melhorá-la, podem ficar a vontade. Abraços!
<?php
/**
* Classe para conexão com a base de dados MySQL
*
* @author Leonardo Tavares
*/
class Conexao {
/**
* Nome do servidor, onde está o banco de dados
* @var string
*/
protected $servidor;
/**
* Nome do usuario do banco de dados
* @var string
*/
protected $usuario;
/**
* Senha do banco de dados
* @var string
*/
protected $senha;
/**
* Nome da tabela do banco de dados
* @var string
*/
protected $tabela;
/**
* Nome do banco de dados onde estão as tabelas
* @var string
*/
protected $bancoDeDados;
/**
* Indica o ponteiro de uma conexão MySQL
* @var string
*/
protected $identificador;
/**
* Define valores para algumas propriedades da classe que serão usadas na conexão
*
* @param string $servidor - O servidor do banco de dados (geralmente localhost em máquinas locais)
* @param string $usuario - Usuário para acessar o banco de dados
* @param string $senha - A senha do usuário
* @param string $bancoDeDados - Nome do banco de dados que contém as tabelas
*/
public function __construct($servidor ='', $usuario ='', $senha ='', $tabela ='', $bancoDeDados=''){
$this->servidor = $servidor;
$this->usuario = $usuario;
$this->senha = $senha;
$this->tabela = $tabela;
$this->bancoDeDados = $bancoDeDados;
}
/**
* Realiza a conexão com o banco de dados
*
* @return object - O identificador da conexão
*/
public function conectar(){
try{
$this->identificador = new mysqli($this->servidor, $this->usuario, $this->senha, $this->bancoDeDados);
if (mysqli_connect_errno() != 0){
throw new Exception('Não foi possível conectar ao banco de dados.');
}
}catch(Execption $db_erro){
echo $db_erro->getMessage();
}
return $this->identificador;
}
/**
* Termina a conexão com o banco de dados
*/
public function fecharConexao(){
if(mysqli_connect_errno() == 0){
$fechar = $this->conectar();
$fechar->close();
}
}
}
?>rafinhaphp se tiver algum informe de erro ou qualquer outra coisa sobre a classe pode falar ;)
Sugiro que você efetue a conexão no método __construct. Quem inicia uma classe de conexão deseja usar o banco de dados, Logo, seria interessante iniciar a conexão no construtor
Outra coisa, defina uma propriedade de classe para armazenar o estado da conexão, ou seja, uma booleano que especifique se a conexão está aberta ou fechada. VocÊ pode usar esse valor para executar a funçõa close() em vez de abrir uma nova conexão sempre que quiser fechá-la.
unica coiza que eu mudaria é:
USAR INGLÊS para da nome as coizas...
não sei se isso seria bom pra você, mas eu gosto de usar o inglês para programar (mesmo sendo muito ruim no inglês, confesso rs)
porque se você reparar bem, tudo é inglês....
>
Outra coisa, defina uma propriedade de classe para armazenar o estado da conexão, ou seja, uma booleano que especifique se a conexão está aberta ou fechada. VocÊ pode usar esse valor para executar a funçõa close() em vez de abrir uma nova conexão sempre que quiser fechá-la.
Beleza Beraldo? Sobre a propriedade para armazenar o booleano, acredito que a propriedade $this->identificador já esta fazendo essa função, ou não?
>
USAR INGLÊS para da nome as coizas...
não sei se isso seria bom pra você, mas eu gosto de usar o inglês para programar (mesmo sendo muito ruim no inglês, confesso rs)
Concordo com o que você disse, mas essa classe foi elaborada com o propósito de se tornar um tutorial, logo acho que pra se associar fica mais fácil deixar alguns termos em português :)
Achei 'estranho' isso:
try{
$this->identificador = new mysqli($this->servidor, $this->usuario, $this->senha, $this->bancoDeDados);
if (mysqli_connect_errno() != 0){
throw new Exception('Não foi possível conectar ao banco de dados.');
}
}catch(Execption $db_erro){
echo $db_erro->getMessage();
} você tá lançando a excessão ai, não não vai conseguir capturá-la ai mesmo.. exemplo:
$c = new Conexao('localhost','root','1234');//a senha correta é 123>
Warning: mysqli::mysqli() [mysqli.mysqli]: (28000/1045): Access denied for user 'root'@'localhost' (using password: YES) in C:\Arquivos de programas\Apache Software Foundation\Apache2.2\htdocs\Conexao.php on line 63
Fatal error: Uncaught exception 'Exception' with message 'Não foi possível conectar ao banco de dados.' in C:\Arquivos de programas\Apache Software Foundation\Apache2.2\htdocs\Conexao.php:65 Stack trace: #0 C:\Arquivos de programas\Apache Software Foundation\Apache2.2\htdocs\Conexao.php(85): Conexao->conectar() #1 {main} thrown in C:\Arquivos de programas\Apache Software Foundation\Apache2.2\htdocs\Conexao.php on line 65
>
>
Outra coisa, defina uma propriedade de classe para armazenar o estado da conexão, ou seja, uma booleano que especifique se a conexão está aberta ou fechada. VocÊ pode usar esse valor para executar a funçõa close() em vez de abrir uma nova conexão sempre que quiser fechá-la.
Beleza Beraldo? Sobre a propriedade para armazenar o booleano, acredito que a propriedade *$this->identificador* já esta fazendo essa função, ou não?
Se for usar $this->identificador, deve deixá-la em off quando não houver conexão. Caso contrário, não conseguirá criar uma ocndição para verificar se está conectado ou não.
PS: Documentação errada. $this->identificador não é uma string.>
erro :
Warning: mysqli::mysqli() [mysqli.mysqli]: (28000/1045): Access denied for user 'root'@'localhost' (using password: YES) in C:\Arquivos de programas\Apache Software Foundation\Apache2.2\htdocs\Conexao.php on line 63
Fatal error: Uncaught exception 'Exception' with message 'Não foi possível conectar ao banco de dados.' in C:\Arquivos de programas\Apache Software Foundation\Apache2.2\htdocs\Conexao.php:65 Stack trace: #0 C:\Arquivos de programas\Apache Software Foundation\Apache2.2\htdocs\Conexao.php(85): Conexao->conectar() #1 {main} thrown in C:\Arquivos de programas\Apache Software Foundation\Apache2.2\htdocs\Conexao.php on line 65
Fiz um teste similar para testar se a exceção iria funcionar e também me deparei com esse erro. Não conheço muito sobre o comportamento da extensão mysqli, apliquei ela na classe para poder estudá-la melhor... :) Tentei algumas coisinhas mais não tive sucesso, apesar de lançar a exceção não é exibida somente a mensagem informando o erro. Achei estranho, na lógica acredito que teria que funcionar, o que acontece?
>
Se for usar $this->identificador, deve deixá-la em off quando não houver conexão. Caso contrário, não conseguirá criar uma ocndição para verificar se está conectado ou não.
PS: Documentação errada. $this->identificador não é uma string.
Entendi obrigado pela dica. Sobre a documentação esqueci de fazer a alteração quando coloquei no tópico rsr, $this->identificador recebe um objeto não uma string...>
Achei estranho, na lógica acredito que teria que funcionar, o que acontece?
Acontece que você não vai capturar um erro no mesmo lugar em que você lança ele.. é um erro na tua lógica.. como me disse um amigo: 'Nunca vi falha ao tentar lançar um erro'.
>
Acontece que você não vai capturar um erro no mesmo lugar em que você lança ele.. é um erro na tua lógica.. como me disse um amigo: 'Nunca vi falha ao tentar lançar um erro'.
Isso passou completamente despercebido huahua. Gostei da frase, vou tratá-la como um dogma ;)
Ainda não consegui achar uma resolução para o problema achado pelo William.
Alguém se habilita?
Exemplo simples:
<?php
class Conexao {
protected $servidor = SERVER;
protected $usuario = USER;
protected $senha = PASS;
protected $bancoDeDados = DB;
public $mysqli;
public function __construct()
{
$this->mysqli = @new mysqli($this->servidor, $this->usuario, $this->senha, $this->bancoDeDados);
if (mysqli_connect_errno() != 0)
throw new Exception('Não foi possível conectar ao banco de dados.');
return $this->mysqli;
}
}
//config.inc.php
define('SERVER', 'localhost');
define('USER', 'root');
define('PASS', '1234');//o correto é 123
define('DB', 'ajax');
try {
$Conexao = new Conexao();//tentando conectar ao banco
}
catch( Exception $e ){
echo $e->getMessage();
}
$query = $Conexao->mysqli->query("SELECT * FROM `cliente`");
echo $query->fetch_object()->nome; única coisa, é que vai ser gerado um **Warning** mesmo assim, pois há um **erro** mesmo.Então com um **@** suprimiriamos o erro:
$this->identificador = @new mysqli($this->servidor, $this->usuario, $this->senha, $this->bancoDeDados);Desculpem-me pela demora... William depois que você me alertou sobre aquela exceção, modifiquei bastante classe e apliquei a dica que o Beraldo citou... Vou postar o novo código para da classe de conexão, qualquer coisa que deixei passar é só falar! Abraços ;)
<?php
/**
* Classe para conexão, com utilização da extensão MySQLi
*
* @author Leonardo Tavares
*/
class Conexao extends mysqli{
/**
* Array que recebe os dados fornecidos para conexão
* @var array
*/
private $db_dados = array();
/**
* Indica o ponteiro de uma conexão MySQL
* @var boolean
* @static
*/
private static $status_con = false;
/**
* Armazena o resultado de possíveis consultas no banco de dados
*
* @var string
*/
private $resultado;
/**
* Recebe os dados para uso na conexão Ex: servidor, usuário, senha, bancodedados
*
* @param string $chave - Índice associativo para o elemento da conexão
* @param string $valor - Valor correspondente ao índice
*/
public function setDados($chave, $valor){
$this->db_dados[$chave] = $valor;
}
/**
* Recupera os valores do array setDados
*
* @return mixed - Array com os dados para a conexão
*/
public function getDados(){
return $this->db_dados;
}
/**
* Realiza a conexão com o banco de dados, utilizando método heradado da classe MySQLi
*
* @return boolean - Identifica se a conexão foi estabelecida
*/
private function conectarBD(){
if(!self::$status_con){
$dados_con = $this->getDados();
if(is_array($dados_con)){
@parent::__construct($dados_con['servidor'],$dados_con['usuario'],$dados_con['senha'],$dados_con['bancodedados']);
if(mysqli_connect_errno() != 0) {
throw new Exception('Não foi possível realizar a conexão com o banco de dados: ' . $dados_con['bancodedados']);
}
return self::$status_con = true;
}
}
}
/**
* Se uma conexão existir, executa uma consuta no banco de dados
*
* @param string - A instrução SQL para uma possível consulta
* @return string - Valores obtidos da consulta no banco de dados
*/
public function executarConsulta($sql){
try{
if($this->conectarBD()){
$this->resultado = parent::query($sql);
if(!$this->resultado){
throw new Exception('Não foi possível executar a consulta');
}else{
return $this->resultado;
}
}
}catch(Exception $erro){
echo $erro->getMessage();
}
}
/**
* Se existir uma conexão ela será fechada
*/
public function fechar(){
if(self::$status_con){
parent::close();
self::$status_con = false;
}
}
}
?>legal.. ficou mais interessante agora.. testei aqui:
$Conexao = new Conexao();
$Conexao->setDados('servidor', 'localhost');
$Conexao->setDados('usuario', 'root');
$Conexao->setDados('senha', '123');
$Conexao->setDados('bancodedados', 'ajax');
$query = $Conexao->executarConsulta("SELECT * FROM cliente");
while( $dados=$query->fetch_object() )
echo $dados->nome.'<br />';você está trabalhando com herança... mas pode fazer **overload**, digitar: executarConsulta toda vez que precisar de uma consulta, vai ser meio custoso..
Por isso, sugiro trocar:
public function executarConsulta($sql){por:
public function query($sql){ Pode ser 'questão de gosto', mas eu tô preferindo passar os dados de conexão: (server, user, senha), como constantes que defino num arquivo de configuração. Mas tá ficando legal... vai implementando ai, que vamos estudando POO !William valeu pela força! :)
Sobre as constantes achei bacana a idéia! Pensei em um arquivo XML com o mesmo intuito das constantes, seria algo assim:
<config>
<banco>
<host>localhost</host>
<usuario>root</usuario>
<senha>123</senha>
<db>nome</db>
</banco>
</config>
Depois era só converter cada campo em um objeto com simplexml_load_file :DEstou pensando em substituir setDados e getDados por __set e __get. Mais tenho uma dúvida sobre overload em si, acho que sei a resposta, mas... Por exemplo, quando se fala em sobrecarga, somente se aplica esse termo com __set e __get - métodos mágicos em geral - ou funções definidas com essa intenção também garantem essa função? A algum tempo tenho essa dúvida...
Abraços!
Estava analisando a classe e achei interessante colocar um método mágico __destruct para fechar a conexão. Para não colocar novamente todo o código, a modificação seria apenas a adição do método assim:
/**
*Fecha a conexão automaticamente após a execução da classe
*/
__destruct(){
$this->fehcar();
}Eu uso o Singleton na minha classe de conexão!
Olá pessoal! Como tinha dito antes, fiz um tutorial sobre a classe para conexão com o bando de dados.
Segue o link -> Classe para conexão com MySQLi Boa leitura. :)
p****, ta daóra em... Tem os tratamentos de erro e taL... LEGAL!!!