Me revoilà avec mon minichat.
J'en perds mon latin, je viens du monde C et là PHP me fait sévèrement transpirer.
Il m'est demandé dans mon TP de créér un lien pour afficher les messages par 5, avec possibilité d'afficher les suivants ou précédents en verifiant de ne pas être en fin ou début de liste.
je suis parti sur ce script qui logiquement est assez simpel (en tout cas en C pas de soucis)
try
{ //lecture de toutes les billets existants
$bdd = new PDO('mysql:host='. $host_name .';dbname='. $database , $user_name , $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$Message=$bdd->query('SELECT count(*) as total FROM message');
$nombreMessage=$Message->fetch();
//calcul du nombre de page pour un affichage de 5 message par page
$nombrePage =(($nombreMessage['total']%5)>0) ? (int)($nombreMessage['total']/5)+1 : (int)($nombreMessage['total']/5);
for ($i=0;$i<$nombrePage;++$i)
{
//affichage par tranche de 5 messages
$sql[$i]='SELECT pseudo,messagetext,dateMessage FROM message ORDER BY ID DESC LIMIT '.($i*5).','.(($i*5)+5);
}
echo 'Nombre de page'.$nombrePage.'<br/>';
echo 'sql ='.$sql[$page].'<br/>';
$lecture=$bdd->query($sql[$page]);
while($ligne=$lecture->fetch())
{
echo '<a style="font-size:1em"><strong>'.htmlspecialchars($ligne['pseudo']).'</strong></a><a style="font-size:small"> ('.$ligne['dateMessage'].')</a> : <a style="font-style:italic">'.htmlspecialchars($ligne['messagetext']).'</a><br/>';
}
$lecture->closeCursor();
//verifie le fil d'ariane afin de déterminer la possibilité d'afficher les messages suivants et//ou précédents
if ($page==0)
{
echo '<a href="index.php?page='.(++$page).'" ><< Messages suivants >></a>';
}
elseif ($page==($nombrePage-1))
{
echo '<a href="index.php?page='.--$page.'" ><< Messages précédents >></a>';
}
else
{
echo '<a href="index.php?page='.--$page.'" > << Messages précédents >> </a>';
echo '<a href="index.php?page='.++$page.'" ><< Messages suivants >></a>';
}
}
catch (Exception $e)
{
die('Erreur : ' . $e->getMessage());
}
?>
j'ai 17 messages et donc 4 pages.
mon sql est donc filtré par la LIMIT x,y
Lorsque je suis en $page=0 pas de soucis, $page s'incrémente et passe à 1;
Dans ce cas je peux cliquer sur précedent ou suivant
Si je clique sur précedent la variable reprend la valeur 0;
mais si je clique sur "messages suivant "et bien $page reste à 1 !!!
j'ai fait un test totalement illogique mais bon parfois les tests empiriques permettent de résoudre pas mal de soucis.
echo '<a href="index.php?page='.--$page.'" > << Messages précédents >> </a>';
echo '<a href="index.php?page='.++$page.'" >h</a>';
echo '<a href="index.php?page='.++$page.'" ><< Messages suivants >></a>';
Et là si je clique sur "Messages suivants" !!! Devinez !!!
$page=2.
Quelqu'un aurait-il une explication logique ???
En somme tu veux faire une pagination ?
Je n'ai pas compris pourquoi tu récupères tes données dans une boucle for :/
Tu as un tutoriel sur la pagination si tu veux t'inspirer ;)
Je ne récupère pas les données, je construis mes requetes en fonction du nombre de page (LIMIT 0,5 ... LIMIT 5, 10 etc ...) puis j'appelle le tableau en fonction de la page sélectionné. Je sais que je refabrique la roue, mais c'est l'idée du tp ....
Voici une vieille fonction de pagination que tu peu utilisé :
/**
* Fonction permettant de generer une pagination
* @param $current_page int page affiche actuellement
* @param $nb_pages int nombre de page total
* @param $link string personalisation du lien
* @param $around int nombre de liens a affiche avant et après la page courante
* @param $firstlast int nombre de liens a affiche au debut et a la fin
* @return string
**/
function pagination($current_page, $nb_pages, $link='?page=%d', $around=3, $firstlast=1) {
$pagination = '';
$link = preg_replace('`%([^d])`', '%%$1', $link);
if ( !preg_match('`(?<!%)%d`', $link) ) $link .= '%d';
if ( $nb_pages > 1 ) {
// Lien précédent
if ( $current_page > 1 )
$pagination .= '<a class="prevnext" href="'.sprintf($link, $current_page-1).'" title="Page précédente">« Précédent</a>';
else
$pagination .= '<span class="prevnext disabled">« Précédent</span>';
// Lien(s) début
for ( $i=1 ; $i<=$firstlast ; $i++ ) {
$pagination .= ' ';
$pagination .= ($current_page==$i) ? '<span class="current">'.$i.'</span>' : '<a href="'.sprintf($link, $i).'">'.$i.'</a>';
}
// ... après pages début ?
if ( ($current_page-$around) > $firstlast+1 )
$pagination .= ' …';
// On boucle autour de la page courante
$start = ($current_page-$around)>$firstlast ? $current_page-$around : $firstlast+1;
$end = ($current_page+$around)<=($nb_pages-$firstlast) ? $current_page+$around : $nb_pages-$firstlast;
for ( $i=$start ; $i<=$end ; $i++ ) {
$pagination .= ' ';
if ( $i==$current_page )
$pagination .= '<span class="current">'.$i.'</span>';
else
$pagination .= '<a href="'.sprintf($link, $i).'">'.$i.'</a>';
}
// ... avant page nb_pages ?
if ( ($current_page+$around) < $nb_pages-$firstlast )
$pagination .= ' …';
// Lien(s) fin
$start = $nb_pages-$firstlast+1;
if( $start <= $firstlast ) $start = $firstlast+1;
for ( $i=$start ; $i<=$nb_pages ; $i++ ) {
$pagination .= ' ';
$pagination .= ($current_page==$i) ? '<span class="current">'.$i.'</span>' : '<a href="'.sprintf($link, $i).'">'.$i.'</a>';
}
// Lien suivant
if ( $current_page < $nb_pages )
$pagination .= ' <a class="prevnext" href="'.sprintf($link, ($current_page+1)).'" title="Page suivante">Suivant »</a>';
else
$pagination .= ' <span class="prevnext disabled">Suivant »</span>';
}
return $pagination;
}
tu doit dans un premier temps récupérer la page actuelle puis calculé les limites de la requête SQL
Merci Couss, mais j'ai surtout besoin de comprendre comment est gérer l'incrémentation et la décrémentation des variables en PHP.
En C lorsque voici comment ca fonctionne
a = 5;
i=++a ; // i=6 et a=6
i=aa++; // i=6 et a=7
dans le cas de mon script ca ne réagit pas de la meme façon et je ne comprends pas pourquoi ???
C'est normal que cela ne fonctionne pas, je m'explique :
Lorsque tu génére ta page, php te génère ceci:
echo '<a href="index.php?page=0" > << Messages précédents >> </a>';
echo '<a href="index.php?page=1" >h</a>';
echo '<a href="index.php?page=2" ><< Messages suivants >></a>';
Explication:
echo '<a href="index.php?page='.--$page.'" > << Messages précédents >> </a>'; ---- $page est à 0 à ce moment la
echo '<a href="index.php?page='.++$page.'" >h</a>'; $page est à 1 à ce moment la
echo '<a href="index.php?page='.++$page.'" ><< Messages suivants >></a>'; $page est à 2 à ce moment la
As tu compris ce que je voulais dire ?
Ta variable doit être dynamique, c'est à dire récuperer la page en cours, puis la traitée:
Exemple:
<?php
$page = $_GET['page'];
if($page <=0 ){
echo '<a href="lol.php?page='.$page.'" > << Messages précédents >> </a><br';
}
echo '<a href="lol.php?page='.++$page.'" ><< Messages suivants >></a>';
SquallX, sur le coup je n'ai pas compris pourquoi tu me posais la question de l'utilité de ma boucle, donc j'ai gratter un peu et me suis rendu compte que j'étais un ane baté ... Mais ca ne réponds pas à mon problème d'incrémentation mais voilà le nouveau code :
<?php
include('infoconnexion.php');
try
{ //lecture de toutes les billets existants
$bdd = new PDO('mysql:host='. $host_name .';dbname='. $database , $user_name , $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$Message=$bdd->query('SELECT count(*) as total FROM message');
$nombreMessage=$Message->fetch();
//calcul du nombre de page pour un affichage de 5 message par page
$nombrePage =ceil($nombreMessage['total']/5);
//vérification que $_GET('page') existe
$page=(isset($_GET['page'])?intval($_GET['page']):0);
//vérification que le n° de page ne soit pas supérieur au nombre de page
$page=($page>$nombrePage ? $nombrePage: $page);
//vérification que le n° de page ne soit pas négatif
$page=($page<0 ? 0: $page);
$lecture=$bdd->query('SELECT pseudo,messagetext,dateMessage FROM message ORDER BY ID DESC LIMIT '.($page*5).','.(5));
while($ligne=$lecture->fetch())
{
echo '<a style="font-size:1em"><strong>'.htmlspecialchars($ligne['pseudo']).'</strong></a><a style="font-size:small"> ('.$ligne['dateMessage'].')</a> : <a style="font-style:italic">'.htmlspecialchars($ligne['messagetext']).'</a><br/>';
}
$lecture->closeCursor();
//verifie le fil d'ariane afin de déterminé la possibilité d'afficher les messages suivants et//ou précédents
if ($page==0)
{
echo '<a href="index.php?page='.(++$page).'" ><< Messages suivants >></a>';
}
elseif ($page==($nombrePage-1))
{
echo '<a href="index.php?page='.--$page.'" ><< Messages précédents >></a>';
}
else
{
echo '<a href="index.php?page='.--$page.'" > << Messages précédents >> </a>';
//echo '<a href="index.php?page='.++$page.'" >h</a>';
echo '<a href="index.php?page='.++$page.'" ><< Messages suivants >></a>';
}
}
catch (Exception $e)
{
die('Erreur : ' . $e->getMessage());
}
?>
il y a peut être une autre façon de faire mais moi j'incrémente comme cela : $page++ (ajoute +1 à la variable page) et je décrémente $page--
Pourquoi tu ne fais pas une boucle pour afficher tes liens ?
for( $i = 1; $i < $nombrePage; $i++ )
{
echo '<a href="index.php?page=' . $i . '">Page n°' . $i . '</a>';
}
EDIT : Au temps pour moi j'ai survolé ton message...
Il me semble que pour incrémenter une variable tu dois faire $var++ et non ++$var. Après je ne suis pas sûr
Merci Spiker pour ta réponse mais c'est ce que je fais, je travaille sur une variable $page qui est initialisée plus haut par un $_GET :
//vérification que $_GET('page') existe
$page=(isset($_GET['page'])?intval($_GET['page']):0);
//vérification que le n° de page ne soit pas supérieur au nombre de page
$page=($page>$nombrePage ? $nombrePage: $page);
//vérification que le n° de page ne soit pas négatif
$page=($page<0 ? 0: $page);
voila le code modifié pour testé :
{
echo 'page :'.$page;
echo '<a href="index.php?page='.--$page.'" > << Messages précédents >> </a>';
echo '<a href="index.php?page='.++$page.'" ><< Messages suivants >></a>';
}
voilà ce que donne l'analyse par chrome
alors j'ai réfléchis la façon dont PHP génère le HTML , grace à ta remarque Spiker et voilà le résultat :
echo '<a href="index.php?page='.--$page.'" > << Messages précédents >> </a>';
$page++;
echo '<a href="index.php?page='.++$page.'" ><< Messages suivants >></a>';
et l'analyse chrome :
Je ne comprend vraiment pas pourquoi tu stock plusieurs requête et ce que tu souhaite faire.
Moi ce que je ferais c'est cela :
<?php
try { //lecture de toutes les billets existants
$bdd = new PDO('mysql:host='. $host_name .';dbname='. $database , $user_name , $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$Message=$bdd->query('SELECT count(*) as total FROM message');
$nombreMessage=$Message->fetchColumn();
}
catch (Exception $e)
{
die('Erreur : ' . $e->getMessage());
}
//Défini le nombre de message a afficher
define('MSG_PER_PAGE', 5);
// Récupère la page courante
$page = (isset($_GET['page']) && is_numeric($_GET['page'])) ? $_GET['page'] : 1;
// Numéro du 1er enregistrement à lire
$limitStart = ($page - 1) * MSG_PER_PAGE;
// Calcul le nombre de page
$nbPages = ceil($nombreMessage / MSG_PER_PAGE);
if($page != 1 && $page > $nbPages) {
// la page demandé existe pas donc tu peut redirigé vers la première page ou autre
}
// Ta requête de selection
$sql = "SELECT pseudo, messagetext, dateMessage FROM message ORDER BY ID DESC LIMIT {$limitStart}, ".MSG_PER_PAGE;
$lecture=$bdd->query($sql);
while($ligne=$lecture->fetch()) {
echo '<a style="font-size:1em"><strong>'.htmlspecialchars($ligne['pseudo']).'</strong></a><a style="font-size:small"> ('.$ligne['dateMessage'].')</a> : <a style="font-style:italic">'.htmlspecialchars($ligne['messagetext']).'</a><br/>';
}
$lecture->closeCursor();
// Puis la pagination via la fonction que j'ai partager juste avant
echo '<p class="pagination tcenter">' . pagination($page, $nbPages) . '</p>';
?>
Couss, si tu regardes bien j'ai changé le code un peu plus haut .... Mais merci de ton aide
Oui j'avais vu mais il y a eu plusieurs version donc j'ai préféré partir de la première au cas ou
en tout cas mis à part quelques modif ca devrait afficher ce que tu souhaite
echo '<a href="index.php?page='.$page - 1.'" > << Messages précédents >> </a>';
echo '<a href="index.php?page='.$page + 1.'" ><< Messages suivants >></a>';