Classe de conexão ao banco usando PDO

Publicado por Leandro Correa dos Santos (última atualização em 22/09/2011)

[ Hits: 9.195 ]

Homepage: http://resenhasdefilmes.com.br

Download meupdo.php




Desenvolvi essa classe para facilitar a utilização do PDO e a manipulação de comandos SQL no desenvolvimento de sites. Script é baseado em um plugin desenvolvido pelo projeto TinyMVC. Apenas adaptei algumas funções. Para utilizar, deve-se configurar o vetor $config no início do código.

Fonte: http://www.tinymvc.com/

  



Esconder código-fonte

<?php
/*      06-09-2011  Leandro Correa dos Santos  <leandro@prestige.com.br>
 *
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */
/**
 * baseado no plugin TinyMVC_PDO, do projeto TinyMVC < http://www.tinymvc.com >
 */
function dump($var){
   echo "<pre>";
   var_dump($var);
   echo "</pre>";
}
function dumpr($var){
   echo "<pre>";
   print_r($var);
   echo "</pre>";
}
# arquivo de configuração
$config['db'] = array(
   'tipo'=>'pgsql',
   'host'=>'servidor',
   'dbname'=>'nomebobanco',
   'user'=>'usuario',
   'password'=>'senha'
);

# string de conexão
$dsn = $config['db']['tipo'].":host=".$config['db']['host'].";dbname=".$config['db']['dbname'].";";

# classe para extensão do PDO
class Banco{
   private $pdo, $busca, $res, $fetch_mode;
   public $numrows, $last_id, $query_params, $last_query;

   public function __construct($config){
      $dsn = $config['tipo'].":host=".$config['host'].";dbname=".$config['dbname'].";";
      try{
         $this->pdo = new PDO($dsn,$config['user'],$config['password']);
      }catch(PDOException $e){
         echo $e->getMessage();
      }
      $this->query_params = array('select'=>'*');
      $this->fetch_mode = PDO::FETCH_OBJ; # tipo de retorno PDO::FETCH_ASSOC: vetor associativo; PDO::FETCH_OBJ: objeto
   }

   public function setNumRows(){ # retorna o numero de linhas
      $this->numrows = (int) $this->result->rowCount();
   }
   public function last_id(){ # retorna o ultimo id
      $this->last_id = (int) $this->result->last_insert_id();
   }

   function select($clausula){ # ajusta cláusulas do select
      $this->query_params['select'] = $clausula;
   }

   function from($from){ # define tabela a ser usada
      $this->query_params['from'] = $from;
   }
   # apelido para from
   function tabela($tabela){
      $this->from($tabela);
   }

   function where($clausula,$valores,$prefixo="AND")
   {   # monta condicoes para o where
      # verifica se cláusula é nula
      if(empty($clausula))
         throw new Exception("Cláusula não pode ser nula");
      # verifica se a condição foi informada (=, <, >, <>, !=)
      if(!preg_match("/[=<>!]/",$clausula))
         # se nao tiver nenhum operador do where, adiciona '='
         if(!preg_match("/(like|not|in)/g",$clausula))
            $clausula .= " =";
      # se nao tiver '?' na clausula, adiciona
      if(strpos($clausula,'?')===false)
         $clausula .= ' ?';

      # chama a função _where (principal) - por padrão, o where é do tipo and
      $this->_where($clausula,(array)$valores,$prefixo);
   }

   function orwhere($clausula,$valores)
   {
      # chama a funcao where, com prefxo OR em vez de AND
      $this->where($clausula,(array)$valores,"OR");
   }

   private function _where($clausula,$valores=array(),$prefixo)
   {
      # define o where propriamente dito
      if(empty($clausula)) # sem condicao, retorna falso
         return false;

      # TODO usar função anti injection aqui para tratar os valores

      # verifica se a quantidade de '?' é a mesma de valores
      if(($count = substr_count($clausula,'?')) && (count($valores) != $count))
         throw new Exception(sprintf("Quantidade de argumentos é diferente da quantidade de valores: '%s' ",$clausula));

      if(!isset($this->query_params['where']))
         $this->query_params['where'] = array();
      return $this->query_params['where'][] = array('clausula'=>$clausula,'args'=>$valores,'prefxo'=>$prefixo);
   }

   function join($tabela,$condicao,$tipo)
   {
      $clausula = " JOIN {$tabela} ON {$condicao} ";
      if(!empty($tipo))
         $clausula = $tipo." ".$clausula;
      if(!isset($this->query_params['join']))
         $this->query_params['join'] = array();
      $this->query_params['join'][] = $clausula;
   }

   function in($campos,$elementos,$lista=false,$prefixo='AND')
   {
      if(!$lista){ # se $lista for true, elementos vem em forma de lista de valores. ex: id in (1,2,3)
         if(!is_array($elementos))
            $elementos = explode(',',$elementos);

         foreach($elementos as $c => $v)
            #$elementos[$c] = $this->pdo->quote($v); # protege contra codigo malicioso
            $elementos[$c] = addslashes($v); # protege contra codigo malicioso

         $clausula = sprintf("{$campos} IN (%s) ",implode(',',$elementos)); # ajusta clausula
      }
      else # valores da clausula in não são uma lista de valores. ex: id in (select * from foo)
         $clausula = sprintf("{$campos} IN (%s)",$elementos); # ajusta clausula
      # manda para o where
      $this->_where($clausula,array(),$prefixo);
   }

   private function _setclause($tipo,$clausula,$args=array())
   {
      if(empty($tipo) || empty($clausula))
         return false;
      $this->query_params[$tipo] = array('clausula'=>$clausula);

      if(isset($args))
         $this->query_params[$tipo]['args'] = $args;
   }

   function orderby($clausula){
      $this->_setclause("orderby",$clausula);
   }

   function groupby($clausula){
      $this->_setclause("groupby",$clausula);
   }

   function limit($inicio,$fim=0){
      if($fim > 0)
         $this->_setclause("limit",sprintf("%d,%d",(int)$inicio,(int)$fim));
      else
         $this->_setclause("limit",sprintf("%d",(int)$incio));
   }

   private function _query_assemble(&$params,$fetch_mode=null)
   {
      if(empty($this->query_params['from'])){
         # verifica se a tabela foi ajustada
         throw new Exception("Tabela(s) não encontrada(s). Verifique o métodos from() ou tabela()");
         return false;
      }
      $query = array();
      $query[] = "SELECT {$this->query_params['select']}";
      $query[] = "FROM {$this->query_params['from']}";

      # monta os joins
      if($this->query_params['join']){
         foreach($this->query_params['join'] as $j)
            $query[] = $j;
      }

      # monta os wheres

      if($where = $this->_assemble_where($where_string,$params))
         $query[] = $where_string;


      /*if($this->query_params['where']){
         foreach($this->query_params['where'] as $w) # proteção anti injection aqui ?
            $query[] = $w;
      }*/

      # monta groupby
      if($this->query_params['groupby'])
         $query[] = "GROUP BY {$this->query_params['groupby']['clausula']}";

      # monta order by
      if($this->query_params['orderby'])
         $query[] = "ORDER BY {$this->query_params['orderby']['clausula']}";

      # monta limit
      if($this->query_params['limit'])
         $query[] = "LIMIT {$this->query_params['limit']['clausula']}";

      # definir sql
      $query_string = implode(" ",$query);

      # grava o ultimo sql executado
      $this->last_query = $query_string;

      # reseta query_params
      $this->query_params = array('select'=>'*');

      # retorna o sql pronto
      return $query_string;
   }


   private function _assemble_where(&$where,&$params)
   {
      if(!empty($this->query_params['where']))
      {
         $where_init = false;
         $where_parts = array();
         $params = array();
         # monta as condições do where
         foreach($this->query_params['where'] as $w)
         {
            if(!$where_init) $prefixo = 'WHERE'; else $prefixo = $w['prefixo'];
#            $prefixo = if(! $where_init) ? 'WHERE' : $w['prefixo'];
            $where_parts[] = "$prefixo {$w['clausula']}";
            $params = array_merge($params,(array)$w['args']);
            $where_init = true;
         }
         $where = implode(" ",$where_parts);
         #echo $where;
         return true;
      }
      return false;
   }

   /** funções query */

   function query($query=null,$params=null,$fetch_mode=null)
   {
      if(!isset($query))
         $query = $this->_query_assemble($params,$fetch_mode);
      return $this->_query($query,$params,0,$fetch_mode);
   }

   function query_all($query=null,$params=null,$fetch_mode=null)
   {
      if(!isset($query))
         $query = $this->_query_assemble($params,$fetch_mode);
      return $this->_query($query,$params,2,$fetch_mode);
   }

   function query_one($query=null,$params=null,$fetch_mode=null)
   {
      if(!isset($query))
         $query = $this->_query_assemble($params,$fetch_mode);
      return $this->_query($query,$params,1,$fetch_mode);
   }


   function _query($query,$params=null, $return_type=0,$fetch_mode=1)
   {
      # define fetch mode padrão
      if(!isset($fetch_mode))
         $fetch_mode = $fetch_mode; # PDO::FETCH_ASSOC

      # prepara a busca
      try{
         $this->result = $this->pdo->prepare($query);
      }catch(PDOException $e){
         throw new Exception(sprintf("Erro do PDO: %s Query: %s ",$e->getMessage(),$query));
         return false;
      }
      try {
         #dumpr($params);
         $this->result->execute($params);
      } catch (PDOException $e) {
         throw new Exception(sprintf("PDO Error: %s Query: %s",$e->getMessage(),$query));
         echo $e->getMessage();
         return false;
      }
      $this->last_query = $query;

      # ajusta o fetchmode
      $this->result->setFetchMode = $this->fetch_mode;

      # verifica o tipo de retorno
      switch($return_type){
         case 1: # query_one
            return $this->result->fetch();
         break;
         case 2: # query_all
            return $this->result->fetchAll();
         break;
         case 0:
         default:
            return true;
         break;
      }
   }

   /** CRUD */

   function update($tabela,$colunas)
   {
      if(empty($tabela)){
         throw new Exception("Não foi possível atualizar. Tabela não foi informada");
         return false;
      }
      if(empty($colunas) || !is_array($colunas) ) # colunas deve existir e ser um vetor
      {
         throw new Exception("Não foi possível atualizar. Requer vetor com os dados");
         return false;
      }
      $query = array("UPDATE {$tabela} SET");
      $campos = array();
      $params = array();
      foreach($colunas as $c => $v)
      {
         # TODO colocar proteção aqui contra sql injection e XSS
         if(!empty($c))
         {
            $i++;
            $campos[$i] = "{$c}=?";
            $params[$i] = addslashes(htmlentities(trim($v)));
         }
      }
      $query[] = implode(',',$campos);

      if($this->_assemble_where($where_string,$where_params)) # passagem de parametros por referencia
      {
         $query[] = $where_string;
         $params = array_merge($params,$where_params);
      }
      $query = implode(' ',$query);

      $this->query_params = array("select"=>"*");

      return $this->_query($query,$params);
   }

   /** inserir */

   function insert($tabela,$colunas)
   {
      if(empty($tabela))
      {
         throw new Exception("Não foi possível inserir os dados. Tabela não foi informada");
         return false;
      }
      if(empty($colunas) || !is_array($colunas))
      {
         throw new Exception("Não foi possível inserir registro. Requer vetor com os dados");
         return false;
      }
      $column_names = array_keys($colunas);
      $query = array(sprintf("INSERT INTO {$tabela} (%s) VALUES ",implode(",",$column_names)));
      $campos = array();
      $params = array();
      foreach($colunas as $c => $v)
      {
         $campos[] = "?";
         $params[] = addslashes(htmlentities(trim($v)));
      }

      $query[] = '(' . implode(',',$campos) . ')';

      $query = implode(' ',$query);

      $this->_query($query,$params);
      return $this->last_insert_id();
   }

   /** delete */

   function delete($tabela)
   {
      if(empty($tabela))
      {
         throw new Exception("Não foi possível excluir registro. Tabela não foi informada");
         return false;
      }
      $query[] = "DELETE FROM {$tabela} ";
      $params = array();
      if($this->_assemble_where($where_string,$where_params))
      {
         $query[] = $where_string;
         $params = array_merge($params,$where_params);
      }
      $query = implode(' ',$query);

      $this->query_params = array("select"=>"*");
      return $this->_query($query,$params);
   }
   # proximo
   function next($fetch_mode=null)
   {
      if(isset($fetch_mode))
         $this->result->setFetchMode($fetch_mode);
      return $this->result->fetch();
   }
}

?>

Scripts recomendados

Formas de trazer dados da consulta utilizando as funções mysql_fetch_array e mysql_fetch_row

Sistema de autenticação, página protegida e registro de usuários

Banco de Dados xD

Base de dados das cidades do Brasil

Script SQL para banco de sistemas de postagens de artigos 1.0


  

Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts