• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Nazgulled

[PHP] Paginação (links)

36 mensagens neste tópico

Num outro lado queriam tirar uma dúvida sobre criar uns links para paginação e eu acabei por reescrever o código de forma que a paginação funcionasse como pretendido. Decidi também posta-lo aqui pois pode ser útil a alguem.

<?php

// Numero de links a mostrar e total de paginas

$pages_show = 5;
$pages_count = 10;

// Que pagina estamos a ver?

if (isset($_GET['page'])) {
$page = $_GET['page'];

// Verifica se a pagina esta dentro dos limites

if ($page < 1) {
	$page = 1;
} elseif ($page > $pages_count) {
	$page = $pages_count;
}
} else {
$page = 1;
}

// Calcula o inicio e fim do ciclo

$start = $page - floor($pages_show/2);
$end = $page + floor($pages_show/2);

/* Define manualmente o inicio e fim do ciclo se
  estivermos nas primeiras ou ultimas paginas */

if ($start < 1) {
$start = 1;
$end = $pages_show;
} else if ($end > $pages_count) {
$start = $pages_count - $pages_show + 1;
$end = 10;
} else {
/* Incrementa 1 valor ao inicio do ciclo se o numero de links
   for par, caso contrario iremos ter um link a mais */

if (!($pages_show%2)) {
	$start++;
}
}

// Define o link para a pagina anterior a actual

if ($page == 1) {
$pages_html = '<< Anterior | ';
} else {
$pages_html = '<a href="'.$_SERVER['PHP_SELF'].'?page='.($page-1).'"><< Anterior</a> | ';
}

//

for ($i = $start; $i <= $end; $i++) {
if ($i == $page) {
	$pages_html .= $i.' ';
} else {
	$pages_html .= '<a href="'.$_SERVER['PHP_SELF'].'?page='.$i.'">'.$i.'</a> ';
}
}

// Define o link para a pagina a seguir a actual

if ($page >= $pages_count) {
$pages_html .= '| Seguinte >>';
} else {
$pages_html .= '| <a href="'.$_SERVER['PHP_SELF'].'?page='.($page+1).'">Seguinte >></a>';
}

// Imprime a paginacao no ecra

echo $pages_html;

?>

O output será tipo:

Página 1:

<< Anterior | 1 2 3 4 5 | Próxima >>

Página 2:

<< Anterior | 1 2 3 4 5 | Próxima >>

Página 3:

<< Anterior | 1 2 3 4 5 | Próxima >>

Página 4:

<< Anterior | 2 3 4 5 6 | Próxima >>

Página 5:

<< Anterior | 3 4 5 6 7 | Próxima >>

Página 6:

<< Anterior | 4 5 6 7 8 | Próxima >>

Página 7:

<< Anterior | 5 6 7 8 9 | Próxima >>

Página 8:

<< Anterior | 6 7 8 9 10 | Próxima >>

Página 9:

<< Anterior | 6 7 8 9 10 | Próxima >>

Página 10:

<< Anterior | 6 7 8 9 10 | Próxima >>

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

ta bakano, inda nao tinha encontrado nenhum memo de jeito, mas este ta mt fixe...

boa...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pessoal, estava eu a adaptar isto ao meu fotolog quando descobri um bug. Supondo que nós definimos para aparecer 5 links de paginação mas apenas existem 3 (ex: 10 items por página e temos 25 items) os 5 links de paginção iriam ser apresentados, quando o 4º e 5º link iriam produzir uma página errada não existente. o mesmo iria acontecer quando tivessemos na última página, neste caso, na 3ª onde iriam ser produzidos o link -1 e 0.

Para contornar o problema, antes de definirmos o $start e $end perguntamos se $pages_count é inferior ao $pages_show. Caso seja, definimos o $start = 1 e o $end = $pages_count. O bloco de código alterado iria ficar do genero:

if ($pages_count < $pages_show) {
$start = 1;
$end = $pages_count;
} else {
// Calcula o inicio e fim do ciclo

$start = $page - floor($pages_show/2);
$end = $page + floor($pages_show/2);

/* Define manualmente o inicio e fim do ciclo se
   estivermos nas primeiras ou ultimas paginas */

if ($start < 1) {
	$start = 1;
	$end = $pages_show;
} else if ($end > $pages_count) {
	$start = $pages_count - $pages_show + 1;
	$end = 10;
} else {
	/* Incrementa 1 valor ao inicio do ciclo se o numero de links
	   for par, caso contrario iremos ter um link a mais */

	if (!($pages_show%2)) {
		$start++;
	}
}
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tenho uma dúvida.

Gostava de saber como saber exactamente o número de páginas de acordo com os items que tenho na BD.

Sugestões?

Abraço

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Divides pelo número de items por página, e se o resto for diferente de zero, adicionas mais um à divisão.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas como faço isso com o recurso ao SQL ?  :-[

Já noutro tópico me tentaram explicar, mas eu não percebi bem :(

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Fazes a query a seleccionar os registos que vais precisar. Depois usas o mysql_num_rows().

$nRegistos = mysql_num_rows($query);

Depois, basta fazeres isto:

//O número 10 é um exemplo.
$nPaginas = $nRegistos / 10;
if ($nRegistos % 10 != 0){
    $nPaginas++;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas, obrigado pela resposta, tenho o seguinte código:

<?php

require_once('../db/ligar.php');

$sql = mysql_query("SELECT ID FROM tv_noticias ORDER BY date");
for ($pass = 0; $pass < mysql_num_rows($sql); $pass++) {
  $nr_items = mysql_num_rows($sql);

// Numero de links a mostrar e total de paginas

$pages_show = 5;
$pages_count = $nr_items / 10;
if ($nr_items % 10 != 0){
    $pages_count++;
}

// Que pagina estamos a ver?

if (isset($_GET['page'])) {
        $page = $_GET['page'];

        // Verifica se a pagina esta dentro dos limites

        if ($page < 1) {
                $page = 1;
        } elseif ($page > $pages_count) {
                $page = $pages_count;
        }
} else {
        $page = 1;
}

// Calcula o inicio e fim do ciclo

$start = $page - floor($pages_show/2);
$end = $page + floor($pages_show/2);

/* Define manualmente o inicio e fim do ciclo se
   estivermos nas primeiras ou ultimas paginas */

if ($start < 1) {
        $start = 1;
        $end = $pages_show;
} else if ($end > $pages_count) {
        $start = $pages_count - $pages_show + 1;
        $end = 10;
} else {
        /* Incrementa 1 valor ao inicio do ciclo se o numero de links
           for par, caso contrario iremos ter um link a mais */

        if (!($pages_show%2)) {
                $start++;
        }
}

// Define o link para a pagina anterior a actual

if ($page == 1) {
        $pages_html = '<< Anterior | ';
} else {
        $pages_html = '<a href="'.$_SERVER['PHP_SELF'].'?page='.($page-1).'"><< Anterior</a> | ';
}

//

for ($i = $start; $i <= $end; $i++) {
        if ($i == $page) {
                $pages_html .= $i.' ';
        } else {
                $pages_html .= '<a href="'.$_SERVER['PHP_SELF'].'?page='.$i.'">'.$i.'</a> ';
        }
}

// Define o link para a pagina a seguir a actual

if ($page >= $pages_count) {
        $pages_html .= '| Seguinte >>';
} else {
        $pages_html .= '| <a href="'.$_SERVER['PHP_SELF'].'?page='.($page+1).'">Seguinte >></a>';
}

// Imprime a paginacao no ecra

echo $pages_html;

?>

No entanto dá-me erro na última linha do código:

Parse error: syntax error, unexpected $end in public_html/v2/lib/pagination.php on line 86

Penso que seja algo mal fechado do código aí em cima, mas não consigo encontrar o quê :thumbsup:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tenta assim. Tirei-te o primeiro For, não precisas dele.

<?php

require_once('../db/ligar.php');

$sql = mysql_query("SELECT ID FROM tv_noticias ORDER BY date");
$nr_items = mysql_num_rows($sql);

// Numero de links a mostrar e total de paginas

$pages_show = 5;
$pages_count = $nr_items / 10;
if ($nr_items % 10 != 0){
    $pages_count++;
}

// Que pagina estamos a ver?

if (isset($_GET['page'])) {
        $page = $_GET['page'];

        // Verifica se a pagina esta dentro dos limites

        if ($page < 1) {
                $page = 1;
        } elseif ($page > $pages_count) {
                $page = $pages_count;
        }
} else {
        $page = 1;
}

// Calcula o inicio e fim do ciclo

$start = $page - floor($pages_show/2);
$end = $page + floor($pages_show/2);

/* Define manualmente o inicio e fim do ciclo se
   estivermos nas primeiras ou ultimas paginas */

if ($start < 1) {
        $start = 1;
        $end = $pages_show;
} else if ($end > $pages_count) {
        $start = $pages_count - $pages_show + 1;
        $end = 10;
} else {
        /* Incrementa 1 valor ao inicio do ciclo se o numero de links
           for par, caso contrario iremos ter um link a mais */

        if (!($pages_show%2)) {
                $start++;
        }
}

// Define o link para a pagina anterior a actual

if ($page == 1) {
        $pages_html = '<< Anterior | ';
} else {
        $pages_html = '<a href="'.$_SERVER['PHP_SELF'].'?page='.($page-1).'"><< Anterior</a> | ';
}

//

for ($i = $start; $i <= $end; $i++) {
        if ($i == $page) {
                $pages_html .= $i.' ';
        } else {
                $pages_html .= '<a href="'.$_SERVER['PHP_SELF'].'?page='.$i.'">'.$i.'</a> ';
        }
}

// Define o link para a pagina a seguir a actual

if ($page >= $pages_count) {
        $pages_html .= '| Seguinte >>';
} else {
        $pages_html .= '| <a href="'.$_SERVER['PHP_SELF'].'?page='.($page+1).'">Seguinte >></a>';
}

// Imprime a paginacao no ecra

echo $pages_html;

?>

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Hmm, realmente apareceu no site, mas apareceu logo:

<< Anterior | 1 2 3 4 5 | Seguinte >>

E o que eu queria mesmo, era que ele me calculasse o número de páginas de acordo com o de items na BD.

Por exemplo, só tenho 2 items na bd. No entanto quero me mostre um máximo de 5 por máximo, e a partir daí fazer a paginação.

Como só tenho dois items deveria-me ter ficado algo só com uma página.

Percebeste? :thumbsup:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para isso basta modificares as duas variáveis no topo do script para se ajustar as tuas necessidades. Usa mysql_num_rows() para veres quantos registos tem a query.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas eu usei, como podes ver no código que postei:

$nr_items = mysql_num_rows($sql);

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Defines a variável $pages_show no ínicio do script, com o número de páginas que quiseres.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Acho que não me fiz entender, eu quero que isso o calcule automaticamente, de acordo com o nr. de items que existir...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Acho que já percebi o que tu queres...

Os teus cálculos estão bem feitos, o número de páginas correcto está lá, mas nos links, só aparece 5. Se tiver mais, o script adapta-se a esse valor quando estiveres na página 5 (como podes ver no exemplo do primeiro post). Se queres que os links para TODAS as páginas apareçam no ecrã tens duas soluções:

Solução fácil:

Iguala o $pages_show ao $pages_count e move esse linha para debaixo do $pages_count.

Solução "difícil":

Usando a solução fácil parte do código fica completamente desnecessário. Os 3 ciclos fors podem ser substituídos por um, e as variáveis de iteração adaptadas ao número total de páginas.

Se o problema não é este, então não estou a perceber definitivamente o que queres...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Deixa-me ver se consigo explicar de outra forma.

Neste momento tenho, 2 items na base de dados, correcto?

Pronto. Como tal, se quero 5 items no máximo por página (atenção só tenho 2!), logo o suposto era só aparecer para escolher a primeira página, certo? Porque as outras não podem existir porque nem existem items suficientes para fazer uma página!

Então o problema é que, só tendo 2 items, na paginação continua a aparecer-me:

<< Anterior | 1 2 3 4 5 | Seguinte >>

Quando supostamente deveria aparecer

<< Anterior | 1 | Seguinte >>

E o Anterior e o Seguinte nem deveriam dar para clicar, pois não existem mais páginas!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Então corrige o script porque pelos vistos não pensei nesse pormenor quando o fiz :)

E para que é isto:

for ($pass = 0; $pass < mysql_num_rows($sql); $pass++) {
  $nr_items = mysql_num_rows($sql);

Pensa bem no que estás a fazer...

Quanto ao resto, tens razão, tem alguns bugs... O script está a precisar de uma revisão para contemplar todos os casos possíveis. Mas eu estou sem tempo e paciência.

Talvez seja melhor criares um outro tópico e mostrares o teu código actual que deves ter mais ajuda do que continuar a discussão aqui. Depois, se chegares a uma solução, posta o teu resultado aqui ou noutro tópico dentro desta mesma secção.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Fizes-te-te entender. Acho é que tu não entendes-te muito bem. :)

Faz isto.

<?php

require_once('../db/ligar.php');

$sql = mysql_query("SELECT ID FROM tv_noticias ORDER BY date");
$nr_items = mysql_num_rows($sql);

// Numero de links a mostrar e total de paginas

$pages_show = 5;
$pages_count = $nr_items / 10;
if ($nr_items % 10 != 0){
    $pages_count++;
}
$pages_show = $pages_count;

// Que pagina estamos a ver?

if (isset($_GET['page'])) {
        $page = $_GET['page'];

        // Verifica se a pagina esta dentro dos limites

        if ($page < 1) {
                $page = 1;
        } elseif ($page > $pages_count) {
                $page = $pages_count;
        }
} else {
        $page = 1;
}

// Calcula o inicio e fim do ciclo

$start = $page - floor($pages_show/2);
$end = $page + floor($pages_show/2);

/* Define manualmente o inicio e fim do ciclo se
   estivermos nas primeiras ou ultimas paginas */

if ($start < 1) {
        $start = 1;
        $end = $pages_show;
} else if ($end > $pages_count) {
        $start = $pages_count - $pages_show + 1;
        $end = 10;
} else {
        /* Incrementa 1 valor ao inicio do ciclo se o numero de links
           for par, caso contrario iremos ter um link a mais */

        if (!($pages_show%2)) {
                $start++;
        }
}

// Define o link para a pagina anterior a actual

if ($page == 1) {
        $pages_html = '<< Anterior | ';
} else {
        $pages_html = '<a href="'.$_SERVER['PHP_SELF'].'?page='.($page-1).'"><< Anterior</a> | ';
}

//

for ($i = $start; $i <= $end; $i++) {
        if ($i == $page) {
                $pages_html .= $i.' ';
        } else {
                $pages_html .= '<a href="'.$_SERVER['PHP_SELF'].'?page='.$i.'">'.$i.'</a> ';
        }
}

// Define o link para a pagina a seguir a actual

if ($page >= $pages_count) {
        $pages_html .= '| Seguinte >>';
} else {
        $pages_html .= '| <a href="'.$_SERVER['PHP_SELF'].'?page='.($page+1).'">Seguinte >></a>';
}

// Imprime a paginacao no ecra

echo $pages_html;

?>

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas, e obrigado pela resposta de ambos.

scorch, podes dizer-me o que mudaste?

Btw, agora realmente só mostra << Anterior | 1 | Seguinte >>, mas sendo possível clicar no Seguinte, ao clicar irá aparecer << Anterior | 1.2 | Seguinte >> (e neste só fica possível clicar no Anterior).

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Só adicionei isto na linha 15:

$pages_show = $pages_count;

Quanto ao Seguinte, como é que tu obténs a página actual?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Como é que obtenho a página actual como assim?

Esse código de paginação está no ficheiro pagination.php, e o meu outro ficheiro que está a listar os vídeos tem um include desse ficheiro.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

A paginação vai servir para tu poderes ver estar na página 3, por exemplo, e poderes ver os conteúdos dessa página, e poderes andar para traz/frente, certo? Como é que tu sabes em que página estás?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Então coloca isto, em principio deve funcionar:

<?php

require_once('../db/ligar.php');

$sql = mysql_query("SELECT ID FROM tv_noticias ORDER BY date");
$nr_items = mysql_num_rows($sql);

// Numero de links a mostrar e total de paginas

$pages_show = 5;
$pages_count = $nr_items / 10;
if ($nr_items % 10 != 0){
    $pages_count++;
}
$pages_show = $pages_count;

$_GET["page"] = $page;

// Que pagina estamos a ver?

if (isset($_GET['page'])) {
        $page = $_GET['page'];

        // Verifica se a pagina esta dentro dos limites

        if ($page < 1) {
                $page = 1;
        } elseif ($page > $pages_count) {
                $page = $pages_count;
        }
} else {
        $page = 1;
}

// Calcula o inicio e fim do ciclo

$start = $page - floor($pages_show/2);
$end = $page + floor($pages_show/2);

/* Define manualmente o inicio e fim do ciclo se
   estivermos nas primeiras ou ultimas paginas */

if ($start < 1) {
        $start = 1;
        $end = $pages_show;
} else if ($end > $pages_count) {
        $start = $pages_count - $pages_show + 1;
        $end = 10;
} else {
        /* Incrementa 1 valor ao inicio do ciclo se o numero de links
           for par, caso contrario iremos ter um link a mais */

        if (!($pages_show%2)) {
                $start++;
        }
}

// Define o link para a pagina anterior a actual

if ($page == 1) {
        $pages_html = '<< Anterior | ';
} else {
        $pages_html = '<a href="'.$_SERVER['PHP_SELF'].'?page='.($page-1).'"><< Anterior</a> | ';
}

//

for ($i = $start; $i <= $end; $i++) {
        if ($i == $page) {
                $pages_html .= $i.' ';
        } else {
                $pages_html .= '<a href="'.$_SERVER['PHP_SELF'].'?page='.$i.'">'.$i.'</a> ';
        }
}

// Define o link para a pagina a seguir a actual

if ($page >= $pages_count) {
        $pages_html .= '| Seguinte >>';
} else {
        $pages_html .= '| <a href="'.$_SERVER['PHP_SELF'].'?page='.($page+1).'">Seguinte >></a>';
}

// Imprime a paginacao no ecra

echo $pages_html;

?>

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora