nyroBlog
Bannière NyroBlog, par Nyro
Image par Nyro - ?

Tag : MySQL


PHP/MySQL : Faire une pagination sur un tri aléatoire

J'ai été confronté tout à l'heure à un problème simple, mais qui peut poser problème : On vous demande de lister les éléments d'une table MySQL sur une page, et d'en faire une pagination. Tout ce qu'il y a de plus normal. Pour faire ça, vous allez jouer sur les LIMIT de votre requète.

Exemple :

SELECT * FROM utilisateur LIMIT 20,10

Où on afficherai la seconde page des utilisateurs, avec 10 affichages.

Maintenant, imagninez qu'on veuille trier cette requête selon les nom des utilisateurs. Il suffirait de faire :

SELECT * FROM utilisateur LIMIT 20,10 ORDER BY nom ASC

Bon, jusque là, pas de problème particulier.

Maintenant vous ne voulez pas un affichage trié par nom, mais aléatoire. Intuitivement, on ferait simplement :

SELECT * FROM utilisateur LIMIT 20,10 ORDER BY RAND()

Ce qui n'est pas totalement faux. Le problème avec cette solution, c'est que lorsque vous allez changer de page, le tri va changer, et il sera donc impossible aux visiteurs d'afficher tous les noms, ce sera complètement cahotique.

La solution consiste à générer un nombre aléatoire en PHP, à l'enregistrer en session, et à le passer à la requête MySQL, dans les parenthèses du RAND, et le tour est joué. Ainsi le nombre alétoire généré sera toujours le même pour la session en cours, et on se retrouver avec le même tri sur toutes les pages.

Le code pour générer et enregistrer le nombre aléatoire en PHP :

$rand = $_SESSION['rand'];
if (empty($rand)) {
srand((float)microtime()*1000000);
$rand = "0.".rand();
$_SESSION['rand'] = $rand;
}

Bien sûr, il faudra que la session soit démarrer avec session_start() plus haut et qu'aucun header n'ai déjà été envoyé (ou bien utiliser ob_start())

Enfin, la requête MySQL devient :

SELECT * FROM utilisateur LIMIT 20,10 ORDER BY RAND($rand)

Et voilà, vous avez une belle pagination avec un tri aléatoire.

English Version of this post

NyrOS, sources disponibles (projet Flash)

NyrOSL'an dernier, en SRC, j'avais fait un projet Personnel Flash. Les seules contraintes étaient d'utiliser certains composants ou éléments de Flash.

Cette application est encore disponible sur le serveur de SRC, mais je n'ai plus aucun contrôle dessus. C'est pas grave, vous pouvez tester sans problèmes.

A noter que les WebServices (utilisé pour la traduction et le Whois) ne fonctionnent plus, sans doute parce qu'ils ne sont plus disponibles.

Et donc, avec tout ça, je vous fournit la documentation de toutes les classes AS (tout le projet n'est fait qu'avec ça), des quelques codes PHP et même d'un javascript. Si ça peut en aider quelques un qui n'arrive pas à trouver la solution. Vous y trouverez en vrac comment faire une classe qui dispatche des événements pour être écouté, des MovieClipLoader, des créations par le code de UI COmponent, des enregistrements en base de donnée via PHP, etc...

Et puis, un fichier important aussi, c'est les sources (Zip, 12 Mo). Amusez-vous bien, et n'hésitez pas à utiliser les bouts de code qui sont dans ce projet !

BjayDev, 1 collègue développeur PHP

BjayDevLorsque j'étais en SRC, j'ai connu plein de gens avec qui j'ai toujours gardé contact.

Parmi eux, il y a JB, ou Bjay pour le net, qui est aussi développeur PHP indépendant.

Il vient de mettre en ligne une nouvelle mouture de son site, que je vous laisse découvrir.

J'aime particulièrement son logo à la "dreamweaver" (même si je n'aime pas ce logiciel) et le mélange du bleu et du vert qui apporte un peu de fraîcheur et de gaieté alors que le printemps arrive à peine.

PhpMyAdmin : Sortie de la version 2.10.0

phpMyAdminLa dernière version de l'appli qui permet de gérer ses bases de données Web est sortie hier en Release.

Une des grandes nouveautés est le Concepteur (ou Designer en anglais) qui permet de faire du Reverse Enginnering d'un simple clic, pour obtenir le MCD de la base de données. Le premier avantage que j'y vois tout de suite : si les tables sont bien faites, avec les clés étrangères existantes, on pourra reprendre des bases de données de quelqu'un d'autre pour en extraire très simplement le MCD, et ainsi commencer à travailler dessus. Le second avantage est pour faire les clés étrangères facilement : en 3 clics, c'est réglé. Et c'est très intuitifs et bien traduit !

Pour ceux qui n'ont pas envie de s'embetter à l'installer mais qui veulent tester, la démo est disponible (Login : root, pas de mot de passe)

Un grand coup de chapeau à toute l'équipe de phpMyAdmin.

Réparer des bases de données MySQL

Il arrive dans certains cas que des bases de données, plus particulièrement des tables, soit rendu illisibles suite à un crash du serveur.

MySQL a tout prévu avant la commande REPAIR TABLE qui permet de récupérer une table crashée, avec généralement une perte de données, la dernière ligne ajoutée (d'où l'utilité des backups récurents).

Rien que ça, c'est bien utile quand on se retrouve dans un phpMyAdmin qui nous sort plein d'erreurs dont ont ne sait pas vraiment d'où elles sortent et dont on ne comprend pas forcément le sens.

Mais imaginez qu'on ait affaire à un serveur dédié avec un nombre conséquent de base de données. Le serveur a crashé, donc on suppose des erreurs sur les tables de toutes les bases. Comment faire pour ne pas avoir à regarder manuellement dans chaque base de données ?

Utilisez la commande mysqlcheck comme suit, à exécuter en SSH par exemple :

mysqlcheck -A --user=USER --password=PASSWORD

Bien sûr, vous aurez pris soin de changer USER et PASSWORD avec ce qui convient, sûrement root pour l'utilisateur.

Ensuite, vous allez voir toutes les tables de chaque base de données défiler, avec la plupart du temps marqué OK sur la ligne, pour vous indiquer qu'il n'y pas d'erreur.

Pour n'afficher que les tables qui sont crashées, vous n'aurez qu'à rajouter un grep :

mysqlcheck -A --user=USER --password=PASSWORD | grep -v "OK"

Enfin, vous n'aurez qu'à exécuter les REPAIR TABLE sur les tables qui ressortent avec des erreurs et vous en aurez terminer. Normalement, la commande mysqlcheck accepte comme paramètre --auto-repair, mais elle n'a pas fonctionnée dans mon cas, je ne sais pas pourquoi.