IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Methode de pagination vrai quelque soit le SGBD [PDO]


Sujet :

PHP & Base de données

  1. #1
    Membre du Club
    Homme Profil pro
    Directeur Technique Backoffice
    Inscrit en
    Janvier 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur Technique Backoffice

    Informations forums :
    Inscription : Janvier 2009
    Messages : 43
    Points : 44
    Points
    44
    Par défaut Methode de pagination vrai quelque soit le SGBD
    Bonjour,

    Je prépare une migration de ma base de données de mysql vers oracle et j'en profite pour passer mon code php d’interrogation de la base sous PDO.

    J'ai un tableau paginé que j'affiche actuellement à partir d'une requete utilisant LIMIT.
    Cependant, LIMIT Oracle connait pas ...

    La version Oracle pour paginer (d'après ce que j'ai pu lire ici et là) c'est d'utiliser ROWNUM ou ROW_NUMBER(), mais là c'est MySQL qui ne connait pas ...

    Je me demande donc s'il existe une méthode toujours vrai à utiliser pour vraiment utiliser PDO sans se préoccuper de la version de la base de données?

  2. #2
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    J'ai fait quelque chose qui va plus ou moins dans ce sens là:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    class PDOStatementIterator extends IteratorIterator implements SeekableIterator, Countable {
     
        protected $_statement;
     
        protected $_count;
     
        public function __construct (PDOStatement $statement) {
            parent::__construct($this->_statement = $statement);
        }
     
        public function seek ($position) {
            if ($position > $this->count() || $position < $this->key())
                throw new OutOfBoundsException("Cannot seek to $position");
     
            for ($i = $this->key(); $i < $position; $i++)
                $this->next();
        }
     
        public function count () {
            if (!isset($this->_count))
    		    return $this->_count = $this->_statement->rowCount();
    	    return $this->_count;
        }
    }
    Elle s'utilise indépendament du SGBD puisqu'elle ne manipule que les instances de PDOStatement. Vu qu'elle implémente iterator, tu peux utiliser le LimitIterator avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    $stmt = $pdo->query('une query qui va chercher ce qui va bien');
    $it = new PDOStatementIterator($stmt);
    $itit = new LimitIterator($it, 5, 5); // partons de 5 et allons à 10 en chantant.
    foreach ($itit as $row) {
      var_dump($row);
    }
    Enjoy.

  3. #3
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    L'idée est bonne mais c'est guère plus portable que d'utiliser un LIMIT puisque sur des SELECT rowCount n'est absolument pas fiable.

    Si la dernière requête SQL exécutée par l'objet PDOStatement associé est une requête de type SELECT, quelques bases de données retourneront le nombre de lignes retournées par cette requête. Néanmoins, ce comportement n'est pas garanti pour toutes les bases de données et ne devrait pas être exécuté pour des applications portables.
    Je viens de tester sur une base sql server et le rowCount() retourne -1. Du coup on peut faire limiter le nombre d'affichage mais pas profiter de l'offset.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Merci de la remarque.

    Il va donc falloir s'orienter soit
    - vers un ORM du style Doctrine ou Propel
    - vers un pattern Adapter

  5. #5
    Membre du Club
    Homme Profil pro
    Directeur Technique Backoffice
    Inscrit en
    Janvier 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur Technique Backoffice

    Informations forums :
    Inscription : Janvier 2009
    Messages : 43
    Points : 44
    Points
    44
    Par défaut
    ah bah j'allais indiquer que c'étais ok pour moi mais je viens de voir les remarques ... :p

    edit: en fait ce n'est pas si ok que ca, si je demande un affichage de 2 résultats, en page 1 j'ai bien 2 lignes mais en page 2 j'ai 4 lignes ...

  6. #6
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Regarde le constructeur de LimitIterator, c'est LimitIterator::__construct(Iterator $it, $from, $count) et pas LimitIterator::__construct(Iterator $it, $from, $to)

  7. #7
    Membre du Club
    Homme Profil pro
    Directeur Technique Backoffice
    Inscrit en
    Janvier 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur Technique Backoffice

    Informations forums :
    Inscription : Janvier 2009
    Messages : 43
    Points : 44
    Points
    44
    Par défaut
    Yes!, Bien vu

    Un grand merci

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    Bonjour,

    Justement moi, je suis sous MySql et j'utilise PHP (version 5.3.0) et j'ai un problème de pagination. En effet, j'ai un formulaire de recherche multi-critères

    <form id="form1" name="form1" method="post" action= "<?php echo $_SERVER['PHP_SELF'];?>" >
    J'ai mis deux tableaux dans ce formulaire: le premier tableau permet de choisir les critères (type de données, thème, sous-thème, commune).

    Et de lancer la recherche en cliquant sur le bouton relatif à cet effet
    <td><input id="Bouton_Recherche" class="Button" value="Rechercher" type="submit" name="Bouton_Recherche"></td>
    Le deuxième tableau affiche le résultat de cette recherche.

    J'ai trouvé une fonction pour faire la pagination (1 2 3 4 ....) dont voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    Function pagination($RecupRequete)
    	{
    		$par_page=5;
    		if(isset($_GET['debut'])){ 
    			$debut=(int)$_GET['debut'];
    		}
    		else{
    			$debut=0;/*page 1 par defaut*/
    		}
     
    		//$q="SELECT * from ".$dbtable."";
    		$q = $RecupRequete;
    		$comptage_lignes_table=mysql_num_rows(mysql_query($q));
    		$mas_pages= ceil($comptage_lignes_table/$par_page);
    		$prev=$debut-$par_page;
    		$next=$debut+$par_page - 1;
     
    		//$q2 = "select * from ".$dbtable." limit $debut,$par_page";
    		$q2 = "$RecupRequete limit $debut,$par_page";
    		echo "<br>", $q2;
    		$get = mysql_query($q2);
    		while($rows = mysql_fetch_assoc($get))
    		{
    			$r[]=$rows;
    		}
    		//mysql_close();
     
    		/*creation navbar*/
    		$navbar ="";
    		if(!($debut<=0)){
    			$navbar .= '<a href="?debut='.$prev.'"><<  </a>';
    		}
     
    		$i=1;
    		for($x=0;$x<$comptage_lignes_table;$x=$x+5){
    			if($debut!=$x){
    			$navbar .= '<a href="?debut='.$x.'"> '.$i.' </a>';
    			}else{
    				$navbar .= '<a href="?debut='.$x.'"> <b>['.$i.'] </b></a>';
    			}
    			$i++;
    		}
     
    		if($debut <= $comptage_lignes_table-$par_page ){
    			$navbar .= '<a href="?debut='.$next.'">  >></a>';
    		}
     
    			return $dat=array(0=>$navbar,1=>$r);
     
    	}
    La pagination marche très bien. Sauf que quand je clique sur un numéro de page, les critères de recherche choisis
    précédents s'effacent, ma page se recharge.

    Alors, ma question de savoir comment faire pour éviter le rechargement de ma page donc le maintien des critères choisis. Je veux que les critères choisis restent quant on clique sur les numéro de page. Si par hasard, tu as un code qui peut me permettre de faire une bonne pagination ou un conseil pour m'orienter, ça m'irai.

  9. #9
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    On s'écarte du problème de départ.

    Si tu veux que la pagination persiste à travers un formulaire tu dois soit:
    - faire passer les paramètres de pagination dans l'url appelée par le formulaire
    - rendre la pagination sensible aux variables de post et les passer dans des inputs hidden
    - mettre la pagination sur cookie
    - mettre la pagination sur session

    Et puis ce code est très laid.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [JDOM] Obtenir un élément quelque soit sa profondeur
    Par totoranky dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 11/10/2006, 14h40
  2. [VB] ouvrir un fichier quelque soit son extension.
    Par gopal dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 05/05/2006, 20h59
  3. Réponses: 4
    Dernier message: 18/01/2006, 17h04
  4. Etirer le bacground quelque soit la résolution de l'écran
    Par hikosaijuro dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 07/09/2005, 14h39
  5. Réponses: 2
    Dernier message: 05/08/2005, 09h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo