Leonardo™ 0 Denunciar post Postado Janeiro 16, 2010 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(); } } } ?> Compartilhar este post Link para o post Compartilhar em outros sites
rafinhaphp 0 Denunciar post Postado Janeiro 16, 2010 p****, ta daóra em... Tem os tratamentos de erro e taL... LEGAL!!! Compartilhar este post Link para o post Compartilhar em outros sites
Leonardo™ 0 Denunciar post Postado Janeiro 16, 2010 rafinhaphp se tiver algum informe de erro ou qualquer outra coisa sobre a classe pode falar ;) Compartilhar este post Link para o post Compartilhar em outros sites
Beraldo 864 Denunciar post Postado Janeiro 16, 2010 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. Compartilhar este post Link para o post Compartilhar em outros sites
rafinhaphp 0 Denunciar post Postado Janeiro 17, 2010 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.... Compartilhar este post Link para o post Compartilhar em outros sites
Leonardo™ 0 Denunciar post Postado Janeiro 17, 2010 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? Compartilhar este post Link para o post Compartilhar em outros sites
Leonardo™ 0 Denunciar post Postado Janeiro 17, 2010 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 :) Compartilhar este post Link para o post Compartilhar em outros sites
William Bruno 1501 Denunciar post Postado Janeiro 17, 2010 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 $c->conectar(); 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 Compartilhar este post Link para o post Compartilhar em outros sites
Beraldo 864 Denunciar post Postado Janeiro 17, 2010 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. Compartilhar este post Link para o post Compartilhar em outros sites
Leonardo™ 0 Denunciar post Postado Janeiro 17, 2010 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? Compartilhar este post Link para o post Compartilhar em outros sites
Leonardo™ 0 Denunciar post Postado Janeiro 17, 2010 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... Compartilhar este post Link para o post Compartilhar em outros sites
William Bruno 1501 Denunciar post Postado Janeiro 17, 2010 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'. Compartilhar este post Link para o post Compartilhar em outros sites
Leonardo™ 0 Denunciar post Postado Janeiro 17, 2010 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 ;) Compartilhar este post Link para o post Compartilhar em outros sites
.:D6:. 0 Denunciar post Postado Janeiro 18, 2010 Ainda não consegui achar uma resolução para o problema achado pelo William. Alguém se habilita? Compartilhar este post Link para o post Compartilhar em outros sites
William Bruno 1501 Denunciar post Postado Janeiro 18, 2010 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); Compartilhar este post Link para o post Compartilhar em outros sites
Leonardo™ 0 Denunciar post Postado Janeiro 18, 2010 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; } } } ?> Compartilhar este post Link para o post Compartilhar em outros sites
William Bruno 1501 Denunciar post Postado Janeiro 18, 2010 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 ! Compartilhar este post Link para o post Compartilhar em outros sites
Leonardo™ 0 Denunciar post Postado Janeiro 18, 2010 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! Compartilhar este post Link para o post Compartilhar em outros sites
Leonardo™ 0 Denunciar post Postado Janeiro 19, 2010 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(); } Fica mais prático ^^ Compartilhar este post Link para o post Compartilhar em outros sites
martinusso 0 Denunciar post Postado Janeiro 20, 2010 Eu uso o Singleton na minha classe de conexão! Compartilhar este post Link para o post Compartilhar em outros sites