Paginação de resultados com MYSQL
Friday, 26. September 2008, 16:02:15
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!











Anonymous # 15. January 2009, 18:57
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
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
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
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
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
Jefferson, da um exemplo pra eu ver o que esta ocorrendo!
Abraços! e obrigado
Anonymous # 30. August 2009, 02:57
Gostaria de parabeniza-lo pelo código!
Muito simples de usar, além de ser OO.