Classe de conexão ao banco usando PDO

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

[ Hits: 9.182 ]

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

NOTÍCIAS ATUALIZADAS E PERSONALIZADAS!

Backup

Script Para Conectar-se Ao Banco de dados PostGreSQL [golfinho/Elefante]

Portal dh4v01

Classe de conexão com banco de dados PostGreSQL [golfinho/Elefante]


  

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