quarta-feira, 24 de outubro de 2012

Como fazer paginação com PHP e MySQL

Olá!

Bom, chega de mistério com esse negócio de criar paginação com php... Vamos lá, de um jeito simples e fácil, beleza?!

Bom, vou partir do princípio que você já possua alguma conhecimento em PHP e MySQL. Usaremos passagem de parâmetro via URL, ok. Para este artigo, usarei conexão com PDO (se você não sabe como fazer, veja aqui).

Banco de dados do exemplo: loja
Tabela do exemplo: tb_produtos

Ok, agora sem mais delongas, vamos nessa!

Vamos trabalhar com dois arquivos, o que faz a busca no banco de dados e o que exibe o resultado (o conteúdo com a paginação). Ah, mas é claro que, se você preferir, pode fazer isso em um arquivo só (desde que você possua conhecimento pleno em php).

Arquivo de consulta ao banco:

A primeira coisa a definir é o limite, o número máximo de resultados por página, e armazenar em uma variável. Vou chamála de "$limite":
$limite = 10;//aqui, vou exibir até 10 registros por página!

Agora, vamos pegar, através de passagem de parâmetro por URL a página que o usuário está vendo (página 1, 2, 3,, 12 enfim...). Faremos isso com o método "GET" e armazenaremos este conteúdo na variável "$pagina":
$pagina = $_GET['pag'];//pega o valor passado por parâmetro e atribui na variável

Devemos lembrar e entender que se não houver nenhuma variável sendo passada, significa que o usuário está vendo a "página  1", correto?! Assim, devemos "dizer" isso ao php, com um "if" simples:
if(!isset($pagina) || $pagina == ''){//se não existir $pagina ou $pagina for igua a "vazio"
    $pagina = 1;//$pagina é igual a um
}

Muito bem, agora começa a complicar um pouquinho...

O início dos registros deverá ser uma variável calculada. Veja, se vamos exibir 10 registros de cada vez, primeiro a faixa será do 1 ao 10, depois, do 11 ao 20, depois, do 21 ao 30... Para isso, usaremos a seguinte expressão:
$inicio = ($pagina * $limite) - $limite;
Ou seja:
supondo que o usuário está na página 1: inicio = (1 * 10) - 10 >> inicio = 0
logo, vai do zero até os próximos dez

supondo que o usuário está na página 2: inicio = (2 * 10) - 10 >> inicio = 10
logo, vai do dez até os próximos dez

supondo que o usuário está na página 5: inicio = (5 * 10) - 10 >> inicio = 40
logo, vai do quarenta até os próximos dez
...
Agora, faça a consulta no banco de dados... com a seguinte query:
$sql = "SELECT * FROM nome_tabela ORDER BY campo LIMIT " . $inicio . "," . $limite;

Se você usar PDO, fica assim:

try{
    $query = $conecta->prepare($sql);
    $query->execute();
    $resultado = $query->fetchAll(PDO::FETCH_ASSOC);
}catch(PDOException $erro){
    echo $erro->getMessage();
    echo '
';
    echo $sql;
}

Precisamos armazenar, em uma variável a quantidade total de registros, para calcularmos quantas páginas teremos. Para isso, faça uma consulta e armazene o resultado, mais ou menos assim:

$sql = "SELECT * FROM nome_tabela";
try{
    $query = $conecta->prepare($sql);
    $query->execute();
    $resultado = $query->fetchAll(PDO::FETCH_ASSOC);
}catch(PDOException $erro){
    echo $erro->getMessage();
    echo '
';
    echo $sql;
}
 $total_registros = 0;
foreach($total_reg as $total){
     $total_registros++;
}

Agora que já sabemos o total de registros e sabemos que cada página terá até dez resultados, precisamos saber quantas páginas teremos.

Exemplo: 
120 registros = 12 páginas
125 registros = 13 páginas
26 registros = 3 páginas

Para sabermos a quantidade de páginas, faremos o seguinte:
$total_paginas = ceil($total_registros / $limite);

Pronto!

Agora, fazemos um bloco de repetição na página que será paginada, pra criar algo como:

<<    <     1    2    3    4    5    6    7    8    9    >    >>

assim:

    if ($paginacao > 1) {
        $anterior = $paginacao - 1;
    } else {
        $anterior = '1';
    }

    if ($paginacao < ($total_paginas - 2)) {
        $proximo = $paginacao + 1;
    } else {
        $proximo = $total_paginas;
    }

    $contador = 0;
    if ($paginacao < 6) {
        $comeca = 1;
        $termina = 9;
    } else if ($paginacao > ($total_paginas - 6)) {
        $comeca = $total_paginas - 6;
        $termina = $total_paginas;
    } else {
        $comeca = $paginacao - 4;
        $termina = $paginacao + 5;
    }

    echo '
';
    echo '' . '<<' . '';
    echo '' . '<' . '';
    for ($link_pagina = $comeca; $link_pagina <= $termina; $link_pagina++) {
        if ($contador < 9) {
            if ($paginacao == $link_pagina) {
                echo '' . $link_pagina . ''; // Escreve somente o número da página sem ação alguma
            } else {
               echo ' ' . $link_pagina . ''; // Escreve o número e o link da página
            }
            $contador++;
        }
    }
    echo '' . '>' . '';
    echo '>>';
    echo '
';


Bom, é claro que você vai colocar um pouquinho de CSS ai, certo... rs

Espero que tenham curtido, pessoal!

Deus abençoe!

3 comentários:

Anônimo disse...

Bruno, estou tentando implementar esse código no meu site, porém estou com dificuldade. Gostaria que quando o usuário clicasse no link galerias do menu, aparecesse uma página com 20 fotos por página. Porém está me dando essa mensagem: Notice: Undefined index: pag in C:\Program Files (x86)\EasyPHP-DevServer-13.1VC9\data\localweb\malcoln\index2.php on line 134

Aqui, a partir do momento que não tenho uma variável pag, não era para o código usar como página 1?

Unknown disse...

Substitui este codigo abaixo:

$pagina = $_GET['pag'];

if(!isset($pagina) || $pagina == ''){//se não existir $pagina ou $pagina for igua a "vazio"
$pagina = 1;
}

Por isto:

$pagina = (isset($_GET["pag"])) ? (int)$_GET["pag"]:1;

Unknown disse...

Oi Bruno, estou tentando fazer implementar o códigos mas não consigo, sempre exibe página de erro. Meu código faz consulta de imóveis, consegui fazer atravez de um filtro que chama a função, é exibido os imóveis e tal, mas não consigo fazer esta paginação de jeito nenhum. Me dá um help ai. Desde já te agradeço.