Back-End

17 nov, 2009

Paginação PHP com o CodeIgniter

Publicidade

Leia os artigos anteriores

Sobrescrevendo métodos do CodeIgniter sem perder suas funcionalidades originais

Operações de banco de dados com o CodeIgniter

Framework CodeIgniter: motivos e modo de usar

*

Continuando a série de artigos sobre o framework CodeIgniter, hoje veremos como fazer paginação com os recursos do framework. Para isso, vou incrementar os mesmos arquivos que usamos nos artigos anteriores.

Usar a paginação do próprio CI é bem prático e ela já possui diversas coisas embutidas, como parametrizar quantos itens aparecerão por página, personalização de cada link podendo-se adicionar classes específicas e manipular depois com CSS, opções de último e primeiro botões aparecendo apenas em caso de essa opção estar fora da cobertura visível na página atual, determinar por parâmetro quantos links aparecem antes e depois de cada página no máximo… tudo isso com a velocidade própria do CI.

Vamos lá. Na classe da camada model tínhamos uma função para listar os dados chamada retornaLista. Vamos usá-la como base para criarmos outra função chamada retornaLista2; essa nova função receberá dois parâmetros: quantidade máxima por página e limite inferior para buscar no banco de dados (a partir de que valor o select retornará). Abaixo está a função criada, esse método já foi apresentado em artigos anteriores.

function retornaLista2($maximo, $inicio)
{
 $query = $this->db->get('exemplo', $maximo, $inicio);
 return $query->result();
}

A função acima irá retornar os dados referentes à pagina atual na listagem.

Agora, na camada de controller, vamos criar o método para criar a paginação.

A primeira coisa é carregar a biblioteca de paginação do CI, chamada “pagination”. Esse carregamento poderia estar no arquivo “autoload”, como visto em artigos anteriores, mas vamos fazê-lo apenas nesse controle pra ficar mais fácil.

$this->load->library('pagination');

Depois, vamos definir um número máximo para registros aparecerem por tela, vamos colocar três como exemplo. Esse é o valor que será passado para a função retornaLista2 no primeiro parâmetro. Agora, vamos criar a variável que será passada no segundo parâmetro da mesma função. Para isso, vamos usar o método “segment” da classe pré-carregada URI. Esse método pega o parâmetro da URI de acordo com a posição, no nosso exemplo temos

index.php/welcome/listar2/

onde o item 1 da URI é: “welcome” e o item 2 é “lista2”. O item 3 está com valor null, já que não foi passado nenhum valor ainda, mas se tivéssemos a seguinte url:

index.php/welcome/listar2/6

o valor 3 da URI seria 6, ou seja, os itens a serem mostrados na página seriam os três próximos itens, iniciando-se a partir do sexto elemento do banco de dados. As duas linhas abaixo criam as duas variáveis necessárias para a função:

$maximo = 3;
$inicio = (!$this->uri->segment("3")) ? 0 : $this->uri->segment("3");

A variável início é setada como 0 em caso de não haver terceiro parâmetro na URI ou o parâmetro da URI em caso contrário.

Voltando para a camada de model, vamos criar um método simples para retornar o total de registros na tabela, isso é necessário para saber links irão existir para a paginação, o método é simples:

function contaRegistros()
{
 return $this->db->count_all_results('exemplo');
}

Dispensa comentários, apenas retorna o número de registros da tabela exemplo.

Agora, novamente na camada de controller, vamos definir os parâmetros necessários para a paginação do CI, são eles: base_url (define a url sem o 3 parâmetro, ou seja, a url sem o parâmetro da pagina atual), total_rows (é o numero total de registros do banco de dados), per_page (número de registros por páginas a ser mostrado na tela), first_link (apenas um texto indicando o link para a primeira página, o padrão é ‘First’), last_link (apenas um texto indicando o link para a primeira página, o padrão é ‘Last’), next_link (apenas um texto indicando o link para a próxima página, o padrão é ‘>’), prev_link (apenas um texto indicando o link para a página anterior, o padrão é ‘<‘).

A configuração final ficará assim:

$config['base_url'] = '/artigos/exemplo/index.php/welcome/listar2';
$config['total_rows'] = $this->Welcome_model->contaRegistros();
$config['per_page'] = $maximo;
$config['first_link'] = 'Primeiro';
$config['last_link'] = 'Último';
$config['next_link'] = 'Próximo';
$config['prev_link'] = 'Anterior';

Agora basta inicializar a classe passando o array $config acima, da seguinte maneira:

$this->pagination->initialize($config);    

Após esses passos, basta armazenar o resultado da paginação no mesmo array que serão armazenados os dados para a tela (nos exemplos usamos o array $param). Para isso, basta o seguinte comando:

$param["paginacao"] =  $this->pagination->create_links();

Assim, essa variável estará disponível na camada view como $paginação.

Pronto, agora vamos chamar a nova função que criamos e chamar um template para mostrar os dados na tela:

$param["pessoas"] = $this->Welcome_model->retornaLista2($maximo, $inicio);
$this->load->view('listar2', $param);

O método do passo-a-passo acima completo ficará assim:

function listar2(){
 $this->load->library('pagination');
$maximo = 3;
 $inicio = (!$this->uri->segment("3")) ? 0 : $this->uri->segment("3");
$config['base_url'] = '/artigos/exemplo/index.php/welcome/listar2';
 $config['total_rows'] = $this->Welcome_model->contaRegistros();
 $config['per_page'] = $maximo;
 $config['first_link'] = 'Primeiro';
 $config['last_link'] = 'Último';
 $config['next_link'] = 'Próximo';
 $config['prev_link'] = 'Anterior';
$this->pagination->initialize($config);
$param["paginacao"] = $this->pagination->create_links();
 $param["pessoas"] = $this->Welcome_model->retornaLista2($maximo, $inicio);
$this->load->view('listar2', $param);
}

Agora basta criar o template da camada view com o nome listar2 (chamamos ele assim na última linha do método acima). O template é quase igual ao que utilizamos nos outros artigos, tem apenas uma chamada para a paginação, abaixo está o listar2.php da camada view:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <title>Listar</title>
</head>
<body>
<h1>listar!</h1>
<?php
 foreach($pessoas as $chv)
 {
 echo $chv->nome." - ";
 echo $chv->idade;
 echo "<br />";
 }
 echo "Número de registros retornados nessa página: " . sizeof( $pessoas );
?>
<hr />
<?php
echo $paginacao;
?>
</body>
</html>

Para testar, adicionei mais registros na tabela que estamos usando de exemplo, agora são 10 itens gravados.

Seguem abaixo os prints das telas de cada uma das quatro páginas listadas com esses dados.

Reparem nas páginas 2 e 3 que não aparecem o último e o primeiro, já que eles já estão visíveis; repare também nas páginas 1 (sem anterior) e 4 (sem próximo), ou seja, a paginação está funcionando corretamente e a navegação não está confusa.