Skip navigation.

Programação Especialista

Artigos de Programação em Geral

Paginação de resultados com MYSQL

, , , , ,

Este é o primeiro artigo que eu estou fazendo à pedido de outra pessoa.
Me perguntaram como eu faria para desenvolver uma classe de paginação de dados mas que pudesse ser utilizada para outras aplicações.
Pensando nisso, desenvolvi uma classe extremamente simples de paginação para que vocês possam ter como base para alterações de acordo com as suas necessidades.

Coisas que você precisa saber para fazer uma classe de paginação:
  • Noções básicas de OOP
  • Conhecimento básico em SQL (para entender o LIMIT)
  • Conhecimento das variáveis globais (GET,POST,SESSION)


Como desenvolver a classe:
Como sabemos o MYSQL fornece uma opção na sua instrução chamada LIMIT, que faz com que o MYSQL limite a quantidade de registros a serem mostrados na seguinte ordem:
SELECT * FROM pessoas WHERE nome = 'Marcus' LIMIT 0,10

Essa instrução do MYSQL retornará os 10 primeiros registros da sua consulta, e se fizermos um limit de 11,10, pegara 10 registros contando como base o registro 11
Para desenvolvermos a classe de paginação devemos pensar somente neste LIMIT, pois ele que irá fazer a paginação dos dados.

Primeiros passos:
  • Definir as propriedades da classe
  • Quais os métodos desta classe
  • Código da classe
  • Como implementá-la nos seus sistemas


Definir as propriedades da classe:
Para desenvolvermos a classe é necessário colocar algumas propriedades para armazenar dados importantes para a paginação, como por exemplo, quantos registros por página devem ser mostrados, ou qual é a quantidade total de registro dentre outras que irei explicar mais pra frente do post.

Quais os métodos desta classe:
Como a classe é bem simples, utilizaremos o contrutor da classe para executar toda a régra de paginação, ai assim que você instanciar o objeto, ja terá automaticamente o retorno da sua paginação

Código da classe:
Utilizei o máximo de comentários possíveis na classe explicando toda a lógica do desenvolvimento,
Algumas propriedades são privadas pois em nenhum momento se tem a necessidade de acessá-las no sistema.
<?php
/**
 * @author Marcus Brasizza
 * @version 1.0.0
 * @category Paginacao de dados
 */
class paginacao{
 /** @access private */
 //Resultados por pagina
 private $rpp;
 //Total de registros
 private $totalregistros;
 // Qual e a proxima pagina
 private $proxima;
 //Total de paginas
 private $totalpaginas;
 //Qual a pagina atual
 private $atual;
 //Conexao do banco
 private $conn;
 //SQL do usuario
 private $sql;
 //SQL do usuario tratada com o LIMIT
 private $sqltratada;
 //Caminho onde esta o script
 private $caminho;
 /** @access public */
 //Div com o navegador entre paginas  ( << e >>)
 public $navegacao;
 // Resultado da query tratada
 public $dataSource;

 /**
  * @param string $path path da pagina
  * @param dataSource $conn Conexao do banco de dados
  * @param string $sql Consulta SQL
  * @param integer $rpp Quantidade de resultados por pagina
  * @param integer $atual Mostra em qual pagina esta a paginacao
  * @return void() nao retorna nada para quem chamou
  */
 function __construct($path,$conn,$sql,$rpp,$atual){
 // Associando os valores nas propriedades
$this->conn = $conn;
$exec = @mysql_query(mysql_real_escape_string($sql),$this->conn) 
or die("ERRO AO EXECUTAR O SQL");
$this->totalregistros = mysql_num_rows($exec);
$this->sql = $sql;
$this->pagina = $path;
$this->rpp = $rpp;
$this->atual = $atual;
$this->proxima = $atual+1;
// Calcula o total de paginas
$this->totalpaginas = ceil($this->totalregistros/$this->rpp);
// Inicio do Limit
$inicio = ($this->atual <=1)?0:((($this->atual-1)*$this->rpp));
// Quantos registros deve pegar
$fim = ($this->rpp);
// Trata a query colocando escapes seguros
$preparado = mysql_real_escape_string($this->sql . " LIMIT $inicio,$fim ");
//Associa o sql na propriedade
$this->sqltratada = $preparado;
// Executa a query
$result = @mysql_query($this->sqltratada) 
or die("ERRO AO EXECUTAR O SQL");;
// Se for vazio retorna false
if(mysql_num_rows($result) <= 0 ){
$this->dataSource = false;
}
else
{// Se tiver algum registro associa o resultado a propriedade
$this->dataSource = $result;
}
 //Verifico que o caminho ja tem querystring
 // Se tiver eu coloco o concatenador &, senao coloco o ?
 $conc = (eregi('[?]',$this->caminho))?'&':'?';
 //Gero a div de navecacao entre os dados
 $pre = ($this->atual <= 1)?' ': '<a href="'.$this->caminho.$conc.'pagina='.($this->atual-1).'"><<</a>';
 $pos = ($this->atual >= $this->totalpaginas)?'  ':'<a href="'.$this->caminho.$conc.'pagina='.($this->atual+1).'">>></a>';
 $informacao = "página $this->atual de $this->totalpaginas ";
 $this->navegacao = "<div id=\"navegacao\">$pre $informacao $pos</div>";
// return @void
 }
}
?>

Como implementá-la nos seus sistemas:
Para utilizar a classe no seu sistema é necessário primeiramente criar uma conexão com o banco de dados no qual você quer fazer a paginação
<?php
$conn = @mysql_connect('localhost','root','root');
mysql_select_db('banco');

Então você deve fazer a verificação para saber em qual página você esta, utilizaremos o GET que é o mais comum para se fazer as paginações
$inicio = (isset($_GET['pagina'])?$_GET['pagina']:1);

Feito isso você deve instanciar o objeto de paginação, obviamente levando em conta que você ja incluiu ele no seu script com o include(_once) ou require(_once)
Lembrando que você deve passar os seguintes parâmetros
  • Pagina para chamar quando passar para a próxima página (normalmente a mesma página)
  • Conexão do banco de dados
  • Qual o SQL que deseja executar (SEM O LIMIT)
  • A quantidade de registros por página
  • No nosso caso o último parâmetro é a variável $inicio que irá informar em qual página estamos.

$sql = "Select * from pessoa";
$paginacao = new paginacao('index.php',$conn,$sql,10,$inicio);

Caso a execução tenha dado certo, a propriedade dataSource conterá o resource dos registros, caso contrário retornará false, então podemos tratar a execução, e executaremos como se estivessemos fazendo um loop normal com o mysql_fetch_array, porém usando como parâmetro o dataSource da paginação:

if($paginacao->dataSource != false){
while ($dados = mysql_fetch_array($paginacao->dataSource)){
echo $dados['nome'].'<br>';
}
}
else{
 echo "ERRO !";
}


Além disso a classe dispõe de uma propriedade chamada navegação, nela o sistema gerou o famoso DB Navigation com os links de Avançar e Voltar os registros, quando a ação for necessária.
echo "<br>";
echo $paginacao->navegacao;
?>


O código completo esta aqui : paginacao.php

Espero que tenham gostado.
Pretendo escrever o próximo artigo sobre:

Carrinho de compras via sessão

mas aceito outras sugestões!

Design Pattern OBSERVER utilizando as interfaces SPLTeoria de desenvolvimento de um carrinho de compras em PHP

Comments

Anonymous 15. January 2009, 18:57

Jonas de Araujo writes:

Parabéns pela iniciativa !

A classe parece bem universal e completa. Estou apenas tendo problema quando utilizo um sql com varios JOIN's. Retorna erro ao executar SQL .

Mas vou verificar o que pode ser, pois a query esta chegando certinha para a funcao.

Agradecido,

Jonas

Anonymous 15. January 2009, 20:08

Jonas de Araujo writes:

Obs.:

Na linha 50 ( $this->pagina = $path; ) tive que mudar a pagina para caminho. Ai a URL do >> foi gerada corretamente ( isso no caso quando ja existem outros GET na url ).

Anonymous 15. January 2009, 20:42

Jonas de Araujo. writes:

Olá Caro Coleta,

Eu estou tendo dificuldades em utilizar este algol quando no SQL tem alguma variavel php para preencher algum valor.

No meu caso eu tenho um WHERE id = '".$id_xxx."' AND xxxx

se eu colocar o valor ( numero inteiro ) do id do usuario funcioa normal, mas com a variavel da errado. La dentro da funcao paginacao quando eu dou um var_dump no SQL ele vem corretamente, com numero certinho.

Voce ja passou por isto ?

Anonymous 16. January 2009, 10:17

Vini writes:

tira o mysql_real_escape_string acho que assim resolve seu problema ! ele ta escapando o " da sua query !

estudantes 26. February 2009, 14:47

Jefferson(estudantes)

Ainda não consegui entender como mostrar na mesma pagina o select que mostrará o tipo da minha procura.
Exemplo: quando eu seleciono a procura por status = 0, indica que a 3 paginas com esse tipo de procura,mas quando eu clico para ver a proxima pagina a pagina vai para uma pagina secundária.
Sendo pagina principal ativa, e pagina secundaria consulta.
E acontecendo isso perde-se os dados ja selecionados da query..
Se puder me orientar, já agradeço.

Anonymous 27. February 2009, 11:44

artigos writes:

Jefferson, da um exemplo pra eu ver o que esta ocorrendo!

Abraços! e obrigado

Anonymous 30. August 2009, 02:57

Anonymous writes:

Gostaria de parabeniza-lo pelo código!
Muito simples de usar, além de ser OO.

How to use Quote function:

  1. Select some text
  2. Click on the Quote link

Write a comment

Comment
(BBcode and HTML is turned off for anonymous user comments.)

If you can't read the words, press the small reload icon.


Smilies