CLASS DE PAGINATION

malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 - 28 déc. 2006 à 14:43
cs_omelhor Messages postés 1 Date d'inscription vendredi 21 juillet 2006 Statut Membre Dernière intervention 31 décembre 2011 - 31 déc. 2011 à 12:19
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/40881-class-de-pagination

cs_omelhor Messages postés 1 Date d'inscription vendredi 21 juillet 2006 Statut Membre Dernière intervention 31 décembre 2011
31 déc. 2011 à 12:19
bonjour,

Je viens de tomber sur cette classe, et je me demandai comment l'utiliser
Est'il possible d'avoir un exemple d'utilisation de cette classe avec l'url rewriting ?
Je suppose qu'il faut utiliser le .htaccess ?

Merci beaucoup
_klesk Messages postés 70 Date d'inscription jeudi 14 avril 2005 Statut Membre Dernière intervention 20 août 2008
29 févr. 2008 à 17:22
@hindioumax :
Si tu est en php4 c'est foutu pour toi ^^, enfin pas sans modif en tous cas.

@NainPuissant

J'ai voulu essayer le space_besore et space_after mais ça ne marche pas, car il faut mettre
for ($j = 0; $j <= $this->space_before; $j++)
{
$display .= ' ';
}

$display .= $this->separator;
for ($j = 0; $j <= $this->space_after; $j++)
{
$display .= ' ';
}

car pas défaut il ne prend qu'un espace si on ne lui indique pas le non breakable space, (enfin le navigateur).

voila.

mis à part ça j'ai du aussi modifier de façon à pourvoir utiliser mes variable déjà en $_GET car,
soit :

Ça na pas été gérer

Soit :

J'ai pas vu et/ou compris comment faire.

:)
hindioumax Messages postés 3 Date d'inscription dimanche 20 mai 2007 Statut Membre Dernière intervention 23 novembre 2007
23 nov. 2007 à 09:06
Bon j'ai un petit problème en serveur distant (OVH), la classe ne semble pas fonctionner.
Pourtant en local tout fonctionne à merveille.

Erreur PHP:
"Can't access to private property::$separator..."

Apparement la classe n'arrive pas récuperer les variables d'option.

Une aide ? Je me demande si c'est pas une histoire de version de php ...

:(
hindioumax Messages postés 3 Date d'inscription dimanche 20 mai 2007 Statut Membre Dernière intervention 23 novembre 2007
16 nov. 2007 à 14:56
Excellente source, c'est exactement ce que je recherchais. En url rewriting = false, j'ai du toutefois apporter quelques modif sur la classe. En url rewriting = false, j'avais les même problème d'url (avec seulement le &p= après mon host)

J'ai ajouté aussi un paramètre d'option pour définir une classe css.
Maintenant ca fonctionne impeccable.

Merci encore :)


Pour ceux que ca interresse voici les modifs que j'ai fait (sans url rewriting activé):

dans la classe 'pagination', en haut dans les déclarations :
 * @var définition de la classe css des liens
 * @access private
 */	private $classe_css = '';
/**	
 * @var options disponibles
 * @access private
 */	private $options = array(
'nb_datas',
'data_per_page',
'nb_link_per_page',
'url',
'url_rewriting',
'var_page',
'space_before',
'space_after',
'separator',
'classe_css'
);


Les fonctions modifiées qui prenne en compte la variable 'classe_css' + correction URL pour la navigation des pages:
/**
 * Génère les liens
 */	private function generateLink()
{
if ($this->url_rewriting)
{
$this->link = $this->url;
$this->next_page = sprintf($this->url, $this->current_page + 1);
$this->previous_page = sprintf($this->url, $this->current_page - 1);
$this->first_page = sprintf($this->url, 1);
$this->last_page = sprintf($this->url, $this->nb_pages);
}
else
{
$this->link = strstr($this->url, '?') ? '&' : '?';
$this->link .= $this->var_page . '=';
      $this->next_page     = $this->url . $this->link . ($this->current_page + 1);
      $this->previous_page = $this->url . $this->link . ($this->current_page - 1);
$this->first_page    = $this->url . $this->link . 1;
      $this->last_page     = $this->url . $this->link . $this->nb_pages;
}
}
/**
 * Retourne le lien de la première page si la page courante est supérieur à 3 et celui de la page précédente
 *
 * @return string
 */	public function getFirstLinks()
{
$display = '';
if ($this->current_page != 1)
{
if ($this->current_page >= 3)
{
$display .= ' [' . $this->first_page . ' <<] ';
}
$display .= ' [' . $this->previous_page . ' <] ';
return $display;
}
}
/**
 * Retourne le lien de la page suivante et celui de la dernière page si la page courante n'est pas égale au nombre de pages
 *
 * @return string
 */	public function getLastLinks()
{
$display = '';
if ($this->current_page != $this->nb_pages)
{
$display .= ' [' . $this->next_page . ' >] ';
if ($this->current_page <= $this->nb_pages - 2)
{
$display .= ' [' . $this->last_page . ' >>] ';
}
return $display;
}
}
/**
 * Retourne la liste des liens avec le séparateur si il n'est pas vide : 0 | 1 | 2 | 3 | 4
 *
 * @return string
 */	public function getLinks()
{
$display = '';
for ($i = 1; $i <= $this->nb_pages; $i++)
{
if ($i - 1 < ($this->current_page + $this->nb_link_per_page) && $i + 1 > ($this->current_page - $this->nb_link_per_page))
{
if ($i == $this->current_page)
{
$display .= '' . $i . '';
}
else
{
if ($this->url_rewriting)
{
$url = sprintf($this->link, $i);
}
else
{
$url = $this->url . $this->link . $i;
}
$display .= '['. $url . ' ' . $i . ']';
}
if ($i != $this->current_page + $this->nb_link_per_page && $i != $this->nb_pages)
{
for ($j = 0; $j <= $this->space_before; $j++)
{
$display .= ' ';
}
$display .= $this->separator;
for ($j = 0; $j <= $this->space_after; $j++)
{
$display .= ' ';
}
}
}
}
return $display;
}


Construction de l'objet :
$options = array(
'nb_datas' => $count, // Avec une base de donnée
// 'nb_datas' => count($datas), // Avec un array
'data_per_page' => 1,
'nb_link_per_page' => 10,
'url' => 'index.php?p='.$id_page, // Sans url rewriting
// 'url' => 'index-%d.html', // Avec url rewriting
// 'url_rewriting' => true, // Avec url rewriting
'var_page' => 'display',
'classe_css' => 'pagination'
);

$pagination = new Pagination($options);
$pagination->separator = '-';

// etc ...


:)
cs_zeguizmo Messages postés 138 Date d'inscription vendredi 1 août 2003 Statut Membre Dernière intervention 16 juillet 2009
14 oct. 2007 à 13:59
Bonne remarque de seulunami, la source comme elle est proposée là ne fonctionne pas en mode url rewriting = false.

La modification qu'il propose fonctionne.

Merci pour ton travail NainPuissant, c'est du bon boulot.

A+
Popop56 Messages postés 2 Date d'inscription vendredi 27 octobre 2006 Statut Membre Dernière intervention 16 mai 2007
16 mai 2007 à 16:40
Parfait NainPuissant. Cela marche maintenant parfaitement ! Merci pour ce beau code :)
cs_NainPuissant Messages postés 12 Date d'inscription mardi 4 octobre 2005 Statut Membre Dernière intervention 26 septembre 2007
16 mai 2007 à 14:52
@Popop56
Problème régler cela devrait fonctionné désormais ;)
Popop56 Messages postés 2 Date d'inscription vendredi 27 octobre 2006 Statut Membre Dernière intervention 16 mai 2007
14 mai 2007 à 20:43
J'ai un petit problème avec cette classe. Les liens pour aller à la premier page,la dernière page etc (les liens >, >>, <...) ne fonctionne pas. Il me renvoie à la racine du site. J'ai l'url rewriting activé.
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
3 avril 2007 à 02:32
Normal c'est du php 5... .. .

@ tchaOo°
notestablished Messages postés 25 Date d'inscription dimanche 25 avril 2004 Statut Membre Dernière intervention 3 avril 2007
3 avril 2007 à 02:06
moi je viens de trouver cette source...elle m'a tout de suite plus parce que je cherche une class comme celle-ci depuis très longtemps ( j'avais laissé tombé puis je viens de reprendre en fait)

mon problème c'est que la source ne marche par..je suis chez free ( pê est-ce cà ? ) mais dès la ligne 4 il me dit qu'il y a une erreur de syntaxe...

merci de m'aider si vous pouvez ou avez le temps
seulunami Messages postés 1 Date d'inscription samedi 17 mars 2007 Statut Membre Dernière intervention 17 mars 2007
17 mars 2007 à 14:18
très bon travail NainPuissant

Dans ligne 129,
j'ai eu un problem avec le link , mon link ete:
clientes.php?tipo=c

j'ai obtenu seulmente le link "&p=..."

j'ai changé pour:

$this->link = $this->url . ( strpos($this->url, '?') !==false ? '&' : '?' ) ;

et travail bien, je ne sais pas porqoui
a bientôt
cs_NainPuissant Messages postés 12 Date d'inscription mardi 4 octobre 2005 Statut Membre Dernière intervention 26 septembre 2007
8 févr. 2007 à 10:44
Voilà exemple rajouté :)
nizouille Messages postés 3 Date d'inscription vendredi 28 mai 2004 Statut Membre Dernière intervention 5 février 2007
5 févr. 2007 à 20:10
Hello,

Pourriez-vous m'indiquer un exemple d'intégration de votre fonction avec un mysql_query, pcq là je patauge pour l'intégrer à mon site.

Merci de votre aide,

Benjamin
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
5 janv. 2007 à 17:53
En fait ta class ne devrait pas se soucier de l'origine de la variable "page"... page devrait pouvoir provenir de $_GET, $_POST, $_COOKIE ou de toute autre source (variable php, résultat de requete sql, etc)... c'est au developpeur de la passer en paramètre sa récupération ne concerne pas ta classe... d'une part parce que ça n'est pas son boulot d'autre part parce que ça simplifie son utilisation... .. .

@ tchaOo°
cs_NainPuissant Messages postés 12 Date d'inscription mardi 4 octobre 2005 Statut Membre Dernière intervention 26 septembre 2007
3 janv. 2007 à 16:27
Et des ; lignes 213 et 220 >.< enfin je corrigerais ça plus tard
guill76 Messages postés 193 Date d'inscription mercredi 24 août 2005 Statut Membre Dernière intervention 3 juin 2016
3 janv. 2007 à 16:03
Il manque des parenthèses fermantes lignes 236 et 247.
cs_NainPuissant Messages postés 12 Date d'inscription mardi 4 octobre 2005 Statut Membre Dernière intervention 26 septembre 2007
3 janv. 2007 à 13:39
Salut,

Hmm elle ne fonctionne juste par des paramètres en GET mais je pourrais rajouté les paramètres en POST :)

Ps : j'ai modifié la source sans la tester et apparemment elle ne fonctionne pas et a mon boulot je ne peux pas la déboguer comme on a juste php4 >.< enfin désolé :x
cs_xmag Messages postés 23 Date d'inscription mercredi 23 juillet 2003 Statut Membre Dernière intervention 11 juin 2007
3 janv. 2007 à 10:47
Salut,

Très bien cette source mais est-ce qu'elle fonctionne si tu dois passer des paramètres en POST de page en page (par exemple tu as un formulaire de recherche et il y a plusieurs pages de réponses à ta requêtes multicritères)?
(Désolée, je n'ai pas regardé à fond le code, c'est juste une question pour ceux qui recherchent ce genre de pagination ;-))
guill76 Messages postés 193 Date d'inscription mercredi 24 août 2005 Statut Membre Dernière intervention 3 juin 2016
1 janv. 2007 à 14:36
Ouais mais les methodes getFirstlinks() ,getLastlinks et getLinks sont plus spécialisés que les autres, donc dans ce cas ci, Il me semble que cela n'allègerait pas grandement le code. Mais pour les autres ,tu as raison.
et pourquoi pas donc.
public function __get($name)
{
if (property_exists($this,$name)
{
return $this->$name;
}
$getter='get'.$name;
if(method_exists($this,$getter))
{
return $this->$getter();
}
}
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
1 janv. 2007 à 09:22
Là, on en revient à ce qu'on disait...
Pourquoi ne pas renvoyer directement ta propriété dans la méthode __get () ?? Plutôt que d'appeler dans __get () une autre méthode qui elle va renvoyer la propriété...?
guill76 Messages postés 193 Date d'inscription mercredi 24 août 2005 Statut Membre Dernière intervention 3 juin 2016
31 déc. 2006 à 16:55
Salut,
Un tout petit truc qui ne mange pas de pain:
Vu que t'as fait plein de methodes getProp, et par commodités pour leur appel tu pourrais faire un petit truc dans le style:

public function __get($name)
{
$getter='get'.$name;
if(method_exists($this,$getter))
{
return $this->$getter();
}
}
Tu pourrais récupérer comme ça en lecture plus simplement toutes tes propriétés privés ou protégées en utilisant $property = $this->Prop.
Mais bon c'est du chipotage.
Naixn Messages postés 455 Date d'inscription mardi 17 septembre 2002 Statut Membre Dernière intervention 22 juillet 2007
29 déc. 2006 à 14:31
Je vois qu'on est tous d'accord.
Faire une méthode pour un return d'appel d'une fonction, c'est idiot... :)

"Mais je comprend ton point de vue, il est vrai que quelques fois, ca rend le code plus lisible. (je le sais, je le fais moi même :p )"
>> C'est pour ça que je disais qu'ici, ça n'était pas vraiment nécessaire, mais quand j'ai vu la taille du construct, même si raisonnable, ça m'est venu à l'idée, donc bon, j'ai dis. XD
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 3
29 déc. 2006 à 14:28
Oui entre autre :)

Pour moi, la sous-division d'une tache en multiples méthodes de classe revient à dire qu'on utilise ses "sous-taches" plus d'une fois.

Si ca n'est pas le cas, autant le mettre dans le bloc concerné et on en parle plus :)


Une méthode, c'est comme une fonction, ca doit réaliser quelque chose qui soit "générale" au maximum. Mais je comprend ton point de vue, il est vrai que quelques fois, ca rend le code plus lisible. (je le sais, je le fais moi même :p )
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
29 déc. 2006 à 14:25
Bah pourquoi pas. Disons, si tu as des initialisations qui nécessitent des méthodes, car ce sont de véritables "fonctions" complexes, ok, évidemment.
Mais s'il s'agit de faire :
$this -> maChaine = monTrim ($maChaine);

avec
private function monTrim ($sChaine) {
return trim ($sChaine);
}

c'est clairement un problème pour l'optimisation.
Mais s'il s'agit de faire appel à une méthode complexe, why not, évidemment.
Et plus encore s'il s'agit d'une initialisation qui peut être réutilisée plus tard.

Je pense que c'est dans le sens de mon exemple que FhX l'entendait.
Naixn Messages postés 455 Date d'inscription mardi 17 septembre 2002 Statut Membre Dernière intervention 22 juillet 2007
29 déc. 2006 à 14:17
Raaaa tu me prends au mot XD
Nan bon, je vais essayer d'être clair.

La classe présentée ici n'a rien d'idéale. La méthode _calculteMyOwnSHA1 déjà montre bien que pour une raison X ou Y, j'avais envie de refaire sha1. J'aurais pu mettre : _calculateMyOwnFileHash()... C'eût été plus clair.

Pour les commentaires, je suis d'accord que j'ai oublié de les mettres, mais j'en ai pas mis parceque voilà ! (non mais ho).

Pour la BDD c'était pareil, c'est un exemple qui m'est venu en tête... Genre une méthode qui appele PDO, qui faire des requêtes au préalable (genre stockage de l'IP ou je ne sais quoi), qui récupère par exemple la date de dernière connexion, et puis hop on continue.
Ce n'était pas une méthode de gestion de BDD hein. Suis pas fou non plus ;)
Mais la faute me reviens : je n'ai pas été assez clair du tout. Désolé.

En fait, la raison pour laquelle je code comme ça, c'est que j'aime bien avoir une méthode pour une action. Donc même si le rôle du constructeur est de construire, et il a donc un rôle multiple, je préfère sous-diviser les tâches pour appeler des méthodes qui ont un rôle unique.
C'est tout :)
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 3
29 déc. 2006 à 13:51
Alors on va faire un petit peu d'optimisation de ta class "Machin" :p

class Machin {
public function __construct($file, $nb) {

// Calcule le hashage SHA-1 du fichier transmis via $file.
$this->_sha1 = sha1_file($file);

// Récupération du nombre totale de page. (à faire dans le constructeur, et seulement par lui *SAUF* si tu comptes rajouter des pages entre temps ! (m'étonnerait m'enfin bon :p) )
$this->_pages = ceil (...);

// Initialisation de la bdd.
$this->_initBDD('...'); // Ca tu ne dois pas AVOIR ! Aucune méthode pour initialiser une base de donnée dans une classe autre qu'une classe faite EXCLUSIVEMENT pour ca !
// Mauvaise utilisation de l'objet dans ce cas ci !

// Ne sachant pas ce que ca fait, je laisse.
$this->_launch('script'); // J'en déduis que ca a une fonction spécial, alors on sait jamais :p

}

}

Un peu de commentaire n'a jamais tué personne. Je t'ai sauvé 2 appels de méthodes, donc au moins 10 lignes de codes en moins :)
Surtout la méthode sha1_file(), pas besoin de la réécrire elle existe déja :)

La clarification, c'est le commentaire ! Pas le nom de la méthode :p
Naixn Messages postés 455 Date d'inscription mardi 17 septembre 2002 Statut Membre Dernière intervention 22 juillet 2007
29 déc. 2006 à 13:39
Non, c'est sûr que dans ton exemple ...
Mais ça dépend de ta façon de coder.
Moi je dis ça pour deux choses :

1/ Esthétique : Quand tu as différentes parties dans ton __construct, du genre assignation, puis calcul, puis affichage de je sais pas quoi, puis lancement, c'est plus compréhensible quand tu met ça sous forme d'appel de méthodes, parcequ'il te suffit de lire le nom des méthodes appelées pour savoir ce que fait le code, sans lire vraiment l'algo utilisé.
genre :
class Machin
{
public __construct($files, $nb)
{
$this->_sha1 = $this->_calculteMyOwnSHA1($file);
$this->_pages = $this->_calculateNbPages($file, $nb);
$this->_initBDD('mysql:host=localhost;dbname=test');
$this->_launch('script');
}
}
Perso je trouve ça plus clair que de tout faire dans le __construct... :)

2/ Pratique : dans un sens, ça te permet des fois de faire des méthodes que tu vas réutiliser par la suite. Par exemple, du settings d'options, que tu pourrais réutiliser pour changer les settings en cours de route.

Après, je l'ai bien dis, c'est pas parceque je pense ça qu'il faudrait l'appliquer à ce code. Il est assez simple et n'as pas forcément besoin de clarification. C'est juste une question d'habitude :)
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
29 déc. 2006 à 13:27
Hello,

d'autant plus qu'un constructeur est censé construire l'objet, selon la sémantique. Donc pour moi aussi ça parait logique d'initialiser les propriétés membres qui doivent l'être dans le constructeur. Et effectivement, pourquoi passer par une méthode tierce alors que l'objet a accès directement à ses propriétés ? (même quand on passe par __set () d'ailleurs : dans l'objet, on ne passe par par __set, me semble t il).
Bref j'avoue être surpris aussi par ta préférence. Mais bon, ça reste une préférence :-)
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 3
29 déc. 2006 à 13:21
Hu ?
J'avoue ne pas tout comprendre.

Le constructeur est LA méthode de construction de ton instance.
Si tu fais une délégation de la construction, tu vas te retrouver avec quelque chose comme ca :

public function __construct() {
$this->x();
$this->y();
$this->z();
}
public function x();
public function y();
public function z();

L'intérêt ? Aucune. Sauf si tu comptes appeler x,y ou z plus d'une fois. Autrement, c'est une perte de temps. Tu vas appeler x fonctions alors qu'une seule suffit => le constructeur.

Découper c'est bien, mais regrouper les choses qui ne s'éxécutent que lors de l'instanciation est mieux.

Je vais pas faire :
public function __construct($x) {
$this->setX($x);
}
private function setX($x) {
$this->x = $x;
}

Ca n'a aucun sens !
Autant faire :
public function __construct($x) {
$this->x = $x;
}
J'ai gagné 3 lignes et un appel de méthode. Multiplie ca par 100 000 par exemple (un gros projet) et tu vois toi même la perte de temps !

Voila :)
Naixn Messages postés 455 Date d'inscription mardi 17 septembre 2002 Statut Membre Dernière intervention 22 juillet 2007
29 déc. 2006 à 11:17
Juste une petite remarque, mais qui n'a rien de "tu devrais faire comme ça", c'est juste que je dis comment j'aurais vu la chose :

Pour moi, le constructeur n'est pas celui qui doit faire toutes les assignations etc.
Je préfère que le constructeur appelle plusieurs petites fonctions qui feront leur petit truc dans leur coin, mais globalement, le constructeur ne FAIT pas. Il organise et appelle, c'est tout.

Encore une fois, je parle juste de ma façon de voir les choses :)
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
28 déc. 2006 à 22:32
Merci :-)
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
28 déc. 2006 à 14:43
Merci de remplir les mots clefs!
Rejoignez-nous