Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Fabyo

Classe Mysqli( mais uma )

Recommended Posts

Bom pessoal eu achei que não iria mais postar classes aqui, ainda mais sobre mysql, por vários motivos

Mas o principal deles é que usando um framework estilo o Zend, nao precisamos mais se preocupar com classes de manipulação de banco de dados, e outro motivo é que o próprio PHP já criou sua classe para manipular o mysql de forma melhorada,foi até esse nome mesmo que deram

new mysqli();

 

http://br.php.net/mysqli

Extensão MySQL Melhorada

 

Por ser uma classe super completa não vejo a necessidade de se criar outra classe e jogar a classe mysqli dentro.

 

Por esses motivos que eu não criei mais nenhuma classe aqui no imasters, apesar de receber vários emails pedindo, se fosse para PHP4 ate valeria a pena, mas como praticamente já morreu o PHP4 então nem perco meu tempo.

 

mas acontece que da para criar uma classe que manipule o mysql, e aprofeite o melhor das 2 classes e ainda incluir outros metodos uteis.

 

por isso apesar de não usar, resolvi criar uma classe simples para manipulação de banco de dados mysql, pra ajudar quem esta começando com OOP sem usar um framework, eu me limitei ao maximo para fazer ela bem simples e funcional

 

E eu me basiei no proprio Zend, assim temos umas vantagens a principio que explicarei a seguir.

por exemplo a classe e singleton, ou seja só vai existir uma estancia dela, mas mesmo assim eu posso usar a classe e conectar em 2 bancos de dados por exemplo.

hoje vou falar muito, entao quem nao gosta de ler, vai direto pro codigo = ).

 

o principal erro do programador quando ele quer fazer uma classe de conexão, ele tenta reinventar a roda e acaba fazendo algo pior do que já existe, um exemplo simples vamos pegar a própria classe Mysqli, se vocês olharem no manual verão que essa classe aceita vários parâmetros, que são os dados de conexão com o banco de dados exe:

http://br.php.net/manual/pt_BR/mysqli.connect.php

$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

 

dai pra nossa classe ser ao menos no mínimo útil temos que manter essa característica.

no exemplo acima eu tenho $mysqli, e essa classe é completa com isso ja posso fazer o que eu quiser, por isso que nao vejo necessidade em criar uma classe sendo que a mysqli ja é tão util, mas se quiserem conferir os metodos que $mysqli tem basta:

 

$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
print_r(get_class_methods($mysqli));

 

se quero fazer uma consulta basta:

 

$result = $mysqli->query("SELECT Name FROM City LIMIT 10");

 

bom agora voltando a falar da classe que eu criei, depois do singleton os metodos uteis que inseri na classe foram

_connect, getConnection, isConnected, closeConnection, query, fetchOne, lastInsertId

 

os nomes são os mesmos usados pelo Zend framework.

 

explicando cada um desses metodos:

_connect: nao devemos sair conectando no banco de dados, temos que conectar somente na hora exata que for usar e fechar em seguida, por isso na minha classe o banco só é aberto assim que usar, mesmo estanciando a classe a conexao só vai ser aberta na hora de executar a query, mas claro como o proprio Zend temos a opção getConnection para abrir a conexao na hora.

 

isConnected como o nome mesmo ja fala, verifica se a conexao com o banco esta aberta retornando true ou false

 

closeConnection fecha a conexao

 

query chamo o metodo query da classe mysqli

 

fetchOne execulto uma consulta que me retorna apenas o primeiro valor encontrado

 

lastInsertId pego o ultimo id inserido.

 

outro detalhe importante na classe é que ela aceita a passagem dos dados por parametros, ou no caso se você definir os dados em um arquivo config.php por exemplo você nao precisa passar os dados ele ira pegar sozinho, procurando pelas constantes, mas os exemplos de uso serao auto explicativos

 

config.php

<?php
define('SERVER', 'localhost');
define('USER', 'root');
define('PASS', '');
define('DB', 'base');
?>

 

famoso init que ja expliquei em outros scripts

 

init.php

<?php
define('BASE_PATH', realpath(dirname(__FILE__)).'/');

error_reporting(E_ALL);
ini_set('display_errors', TRUE);

setlocale(LC_ALL, "pt_BR", "pt_BR.iso-8859-1", "pt_BR.utf-8", "portuguese");
date_default_timezone_set('America/Sao_Paulo');

set_include_path(implode(PATH_SEPARATOR, array(
BASE_PATH.'classes',
get_include_path()
)));

if(!file_exists(BASE_PATH.'config.php')){
exit('Erro config.php nao encontrado');
} else {
require_once BASE_PATH.'config.php';
}

function __autoload($class_name) {
require_once $class_name . '.php';
}

function isPost(){
if($_SERVER['REQUEST_METHOD'] == 'POST'){
	return TRUE;
}
}	

function getPost($campo){
return isset($_POST[$campo]) ? $_POST[$campo] : '';
}

function filter($campo){
$campo = strip_tags($campo);
if (get_magic_quotes_gpc()) {
	$campo = stripslashes($campo);
}
return $campo;
}	
?>

 

db.php

<?php

class DB
{
private static $db;
private static $_config = null;
private $_connection = null;

private function __construct()
{}

public static function getInstance()
{
	if(func_num_args() == 4){
		self::$_config = func_get_args();
	} else {
		self::$_config[0] = defined("SERVER") ? SERVER : '';
		self::$_config[1] = defined("USER")   ? USER   : '';
		self::$_config[2] = defined("PASS")   ? PASS   : '';
		self::$_config[3] = defined("DB")	 ? DB	 : '';
	}		

	if(!(self::$db instanceof DB)){
		self::$db = new DB();	
	}
	return self::$db;
}

protected function _connect()
{
	if ($this->_connection) {
		return;
	}

	if (!extension_loaded('mysqli')) {
		throw new Exception('É necessario a extension Mysqli.');
	}

	if(is_array(self::$_config)){
		$this->_connection = mysqli_init();

		if (!$this->_connection) {
			throw new Exception('mysqli_init failed');
		}		

		$_isConnected = @mysqli_real_connect(
			$this->_connection,
			self::$_config[0],
			self::$_config[1],
			self::$_config[2],
			self::$_config[3]
		);
		if ($_isConnected === false || mysqli_connect_errno()) {
			throw new Exception(mysqli_connect_error());
		}			
	}
}

public function getConnection()
{
	$this->_connect();
	return $this->_connection;
}

public function isConnected()
{
	return ((bool) ($this->_connection instanceof mysqli));
}

public function closeConnection()
{
	if ($this->isConnected()) {
		$this->_connection->close();
	}
	$this->_connection = null;
}

public function query($sql = '')
{
	if($sql != ''){
		$this->_connect();
		return $this->_connection->query($sql);
	}	
}

public function fetchOne($sql = '')
{
	if($sql != ''){
		$this->_connect();
		$rs = $this->_connection->query($sql);
		$re = $rs->fetch_array();
		return $re[0];
	}	
}	

public function lastInsertId()
{
	$mysqli = $this->_connection;
	return (string) $mysqli->insert_id;
}

public function __clone()
{
	trigger_error('Clone is not allowed.', E_USER_ERROR);
}	
}
?>

 

agora exemplos de uso:

 

index.php

 

<?php
require_once "init.php";
//Metodo 1
$db = DB::getInstance();
$db->getConnection();//forçando a conexao
//mas verifico se a conexao foi aberta mesmo
if($db->isConnected()){	
$rs = $db->query("SELECT * FROM Usuarios");// execulto uma query
$obj = $rs->fetch_object();//pego o resultado
echo $obj->Login;//dou um echo no campo

echo $db->fetchOne("SELECT COUNT(*) as total FROM Usuarios");
/*como o resultado faz parte do mysqli, você pode usar tudo que tem nela por exemplo:
$rs->fetch_row();
$rs->fetch_assoc();
$rs->fetch_array();
$rs->fetch_object();*/
}
$db->closeConnection();// fecho a conexao


//Metodo 2 mais direto e pratico
$rs = DB::getInstance()->query("SELECT * FROM Usuarios");
$obj = $rs->fetch_object();
echo $obj->Login;

//Metodo 3 passando os dados de conexao
$db = DB::getInstance('localhost', 'root', '', 'base');
if($rs = $db->query("SELECT * FROM Usuarios")){
$obj = $rs->fetch_object();
echo $obj->Login;// dou um echo no campo
}	
$db->closeConnection();
?>

 

bom com esses exemplos acredito que deu para entender e apartir dele fazer qualquer outro tipo de consulta, e aproveitando o mysqli.

 

db.php.zip

 

bom falei de mais com pouco conteudo, mas espero que minha classe seja util para quem quer começar

 

abraços.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa Fabyo, como sempre você barbariza em seus scripts, ajudando muito a comunidade. Já uso uma classe de conexão MySQLi adptada de uma criada por você!

Vou ver se implemento essa que você criou em um outro site que estou montando!

 

Parabéns pelo bom trabalho! =)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Aproveitando o topico vou postar uma classe simples para manipular session, nao que seja util mas pelo menos é pratico

 

<?php

class Sessao
{
private static $instance;

private function __construct()
{}

public static function getInstance()
{
	if (!(self::$instance instanceof Sessao)) {
		self::$instance = new Sessao();
		if(session_id() == ''){
			session_start();
		}
	}
	return self::$instance;
}

public function get($sessao = null)
{
	return isset($_SESSION[$sessao]) ? $_SESSION[$sessao] : false;
}

public function set($sessao = null, $valor = null)
{
	$_SESSION[$sessao] = $valor;
}

public function destroy()
{
	$_SESSION = array();
	if (isset($_COOKIE[session_name()])) {
		setcookie(session_name(), '', time()-42000, '/');
	}
	session_destroy();
}

public function __clone()
{
	trigger_error('Clone is not allowed.', E_USER_ERROR);
}
}
?>

 

modo de usar exemplo de login:

 

protecao.php

 

<?php
require_once 'init.php';
if(!(Sessao::getInstance()->get('dados'))){
header("Location: login.html");
}
?>

 

gravar a session:

	$dados['nome']		 = "Fabyo";
$dados['nivel_acesso'] = "3";
Sessao::getInstance()->set('dados', $dados);

 

pegar os dados da session:

 

$user = Sessao::getInstance()->get('dados');
print_r($user);

 

destruir a session

 

Sessao::getInstance()->destroy();

Compartilhar este post


Link para o post
Compartilhar em outros sites

Novamente parabéns pelos posts ambos muito bons! =)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Parabéns Fábio, ótimo tuto, agora entro nessa também já estudando...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa pessoal estou a um bom tempo sem postar nada por aqui! :D

 

Minha dúvida se aplica ao controle de erros! Tem-se uma resposta a critérios de conexão, mais quanto à utilização de Query's tenho tido problemas com o retorno de erros, trazendo sempre apenas um erro quanto utilização posterior e não uma definição explicita do erro, exemple em SQL com problema de sintaxe ele retorna um erro na impressão, como utilizando fetch_object(), ele retorna apenas que o objeto não possui valor ou não está declarado, o que posso fazer pra trazer o erro de sintaxe, tentei utilizar por diversas vezes o mysqli_error() sem sucesso.

 

Espero não estar fazendo um questionamento sem fundamento, sou péssimo para expressar dúvidas!

 

Qualquer dificuldade na compreensão do texto acima, por favor falem!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Implemente no método query, algo parecido com:

public function query( $sql = '' )
	{
		if( !empty($sql) )
		{
			try {
				$this->_connect();
				$query = $this->_connection->query($sql);
				
				if( $query ) return $query;
				else throw new Exception ( 'erro: '.$this->_connection->error );				
			}
			catch( Exception $e ) {
				echo $e->getMessage();
				exit();
			}
		}
	}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa não tinha pensado nisso!

 

Vou dar uma verificada e implementar mais uma coisa que já vinha montado, a utilização do prepare(), pra poder verificar antes de inserir infos no db, no caso de inserts! Assim que tiver concluido vou postar por aqui! De qualquer forma vlw!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Falei bobagem, com isso que você montou não precisa de mais nada! Eu utilizava o prepare() pois não estava trantando como OO completamente! Ai acontecia de gravar duas vezes no BD quando em casos de INSERT!

 

Ao invés de fazer da forma que você montou!

   $this->_connect();
      $query = $this->_connection->query($sql);
      if( $query )
         return $query;

Estava utilizando!

   $this->_connect();
   if($this->_connection->query($sql))
      return $this->_connection->query($sql);

Para corrigir isto fiz!

    public function checkQuery($sql='') {
    	if($sql != ''){
			$this->_connect();
			return $this->_connection->prepare($sql);
    	}    	
    }

....
   if($this->checkQuery($sql)) {
      $this->_connect();
      return $this->_connection->query($sql);

De qualquer forma à maneira que você montou está perfeito William! Pois não havia conseguido montar o retorno dos erros! Recuperei o dia perdido, Vlw brother! :D

 

Ae Fabyo da pra incorporar no script original!!! :P

Compartilhar este post


Link para o post
Compartilhar em outros sites

Falei bobagem, com isso que você montou não precisa de mais nada! [..]

 

De qualquer forma à maneira que você montou está perfeito William! Pois não havia conseguido montar o retorno dos erros! Recuperei o dia perdido, Vlw brother! :D

 

Tranquilo cara.. ^_^

não entendi muita coisa do teu script não... mas tá ai! que bom que resolveu e você entendeu.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.