Général
- Présentation
- Les Symboles
- Les Métacaractères
- Les Ancres et Classes
- Les options
- Constantes prédéfinies
- Equivalences
- Créer un motif
- Les POSIX
- Les PCRE
- Les Plus des PCRE
- Les Assertions Part I
- Les Assertions Part II
- Motif conditionnel
- Mysql et les regex
- Url Rewriting
- Optimisation
- Aide mémoire
Les PCRE
Les POSIX
Pratique
Linux
Spécial php
- Conseils et Astuces
- Délimiteur PCRE
- Créer une bdd
- Utiliser du BBcode
- Le binaire
- Faire un panier
- Cases à cocher
- Citations imbriquées
- Colorateur syntaxique
- Les list-box ou combo-box
- Faire un diaporama
- Isset ou empty ?
- Une légende au survol
- Site en plusieurs langues
- Requêtes dynamiques
- Gestion des smiley
- Faire un moteur de template
- Timestamp php/mysql
- Timestamp mysql
- Matcher une adresse email
- Controler des données
Les billets de fred
- Les POSIX... mise en pratique !
- Limiter l'accès à un répertoire
- Alternance de couleurs
- Magic_quotes
- Désactiver les short_tags
- Require ou include : Bench
- Cohérence dans les chaines de caractères
- "echo" : lapin ou tortue ?
- Gérer un formulaire avec plusieurs boutons
- Le formulaire a t'il été soumis ?
- J'ai décidé de grossir
- La guerre des étoiles
- La guerre des boutons
- Headers already sent
- IP, IP, IP, houra !
- Créer un itérateur avec PHP5
- On vous conduit vers la lumière
- Comment utiliser MySQL avec PHP
- Non aux booléens !
- Php.ini : dist /recommended
- Include : gouffre ou fêlure ?
- Simple comme les sessions !
- Simplifier le traitement des erreurs
- Structurez vos applications
- Franchement, t'es trop for !
- Notice: Undefined variable (ou index)
- Proscrire les variables auto déclarées
Créer un itérateur avec PHP5
Quand vous parcourez un tableau en PHP, vous employez la structure de langage "foreach" (lire : Franchement, t'es trop for !). Il serait intéressant de pouvoir en faire de même avec n'importe quelle donnée comme le résultat d'une requête SQL par exemple.La solution la plus simple serait de mettre le résultat dans un tableau, puis de le parcourir avec "foreach", mais c'est un peu idiot car on doit parcourir deux fois les données !
Pour résoudre ce problème, nous allons exploiter une nouveauté de "foreach" introduit dans PHP5 : les itérateurs. En effet, depuis la sortie de la version 5 de PHP, "foreach" n'attend plus obligatoirement un tableau, mais il peut prendre un objet en paramètre. Si cet objet n'est pas un itérateur (je vais vous expliquer après ce qu'est un itérateur), "foreach" va retourner l'ensemble des propriétés publiques de l'objet.
Exemple :
<?php
class Point {
public $x = null;
public $y = null;
function set( $x, $y ) {
$this->x = $x;
$this->y = $y;
}
}
$point = new Point();
$point->set( 3, 7 );
foreach( $point as $clef => $valeur ) {
echo "$clef => $valeur<br />";
}
?>
Ce qui donne :
x => 3
y => 7
Maintenant, si la classe de mon objet implémente l'interface "Iterator", "foreach" ne va plus parcourir les propriétés de mon objet, mais il va appeler différentes méthodes permettant d'adapter son comportement.
Les méthodes introduites par Iterator sont :
* current : retourne l'élément courant
* key : retourne la valeur de la clef courante
* next : positionne sur l'élément suivant (ne retourne rien)
* rewind : positionne sur le premier élément (ne retourne rien)
* valid : indique si on a atteint la fin de la liste d'éléments.
Observez cet exemple :
<?php
class MonIterateur implements Iterator {
private $compteur = 0;
function current(){
echo 'current()<br />';
return 'element de ' . $this->compteur;
}
function key() {
echo 'key()<br />';
return 'clef ' . $this->compteur;
}
function next(){
echo 'next()<br />';
$this->compteur++;
}
function rewind(){
echo 'rewind()<br />';
}
function valid() {
echo 'valid()<br />';
return $this->compteur < 2;
}
}
$iterateur = new MonIterateur();
foreach( $iterateur as $clef => $valeur ) {
echo "*** $clef => $valeur ***<br />";
}
?>
Nous obtenons le résultat suivant :
rewind()
valid()
current()
key()
*** clef 0 => element de 0 ***
next()
valid()
current()
key()
*** clef 1 => element de 1 ***
next()
valid()
Cela nous permet de déduire cet enchaînement :
Iterateur
Remarque : Contrairement à ce que l'on pourrait penser, si vous n'utilisez par la clef de votre itérateur, la méthode "key()" est malgré tout appelée.
Sur cette base, voici le code que l'on pourrait implémenter pour parcourir le résultat d'une requête SQL "SELECT" (utilisation de l'API mysqli) :
<?php
class Select implements Iterator {
private $result = null;
private $current = null;
private $key = 0;
protected $sql = null;
// Constructeur de la classe prennant la requête SQL
// en paramètre.
function __construct( $sql ) {
// Permet de ne pas refaire de connexion
// à la base plusieurs fois
static $mysqli = null;
if( null === $mysqli ) {
// Connexion à la base
$mysqli = new mysqli('localhost', 'user', 'pass', 'db');
}
// Exécution de la requête
$this->result = $mysqli->query( $sql );
assert('is_object( $this->result ); //* Erreur dans la requête SQL' );
}
// Retourne l'enregistrement courant.
function current(){
return $this->current;
}
// Retourne le numéro d'enregistrement
// Attention, cela n'a aucun rapport avec l'indexe de votre table.
function key() {
return $this->key;
}
// Enregistrement suivant
function next(){
$this->current = $this->result->fetch_assoc();
$this->key++;
}
// On positionne sur le premier enregistrement.
function rewind(){
$this->result->data_seek(0);
$this->key = -1;
$this->next();
}
// Le résultat courant est-il correcte ?
function valid() {
return is_array( $this->current );
}
}
// On crée une nouvelle liste
$select = new Select( 'select ch1, ch2 from test' );
// Affichage de la liste
foreach( $select as $clef => $ligne ) {
echo $clef, ' => ', implode(', ', $ligne ), '<br />';
}
?>
Par Frédéric Bouchery
