Articles

Le mois de la fonction PHP : au hasard de PHP

  • Ecrit par Damien Seguy
  • jeudi 12 avril 2007
Image pour le titre du contenu

This document is also available in English en 


Généralement, les logiciels sont destinés à réduire l'incohérence des données, et leur donner un maximum de cohérence et de valeur. Les données sont analysées, validées et mesurées à l'aune de nombreuses règles métier. Si elles ne sont pas bonnes, on tente de les corriger.

Alors pourquoi y-a-t-il tant de fonctions pour introduire des données aléatoires dans les programmes? C'est que cela répond à un besoin métier fréquent. Le hasard est souvent sollicité pour départager des situations où les humains ne sont pas capables de trouver de solution eux-mêmes : on tire au hasard une valeur dans un lot, et si ce n'est pas ce qu'on voulait, on blâme le hasard.
En PHP, il y a deux sources d'informations aléatoires. Les fonctions génératrices et les fonctions mêlantes.

Les fonctions génératrices sont les plus connues. Il s'agit de la fonction rand(), qui retourne une valeur aléatoire entre 0 et RAND_MAX. RAND_MAX est une constante PHP qui définit le plus grand entier positif représenté dans PHP. Vous pouvez utilisez cette constante pour ramener le nombre entre 0 et 1. Si RAND_MAX n'existe pas sur votre plate-forme, utilisez la fonction getmaxrand().

Si vous voulez obtenir un entier dans un intervalle bien défini, vous pouvez donner les bornes de l'intervalle comme arguments.

<?php
echo <a href="http://www.php.net/rand">rand()</a>; 
echo <a href="http://www.php.net/rand">rand()</a> / <a href="http://www.php.net/getmaxrand">getmaxrand()</a>; // entre 0 et 1
echo rand(4,5); // soit 4, soit 5
srand(1);
echo <a href="http://www.php.net/rand">rand()</a>; // un nombre
srand(1);
echo <a href="http://www.php.net/rand">rand()</a>; // le m&ecirc;me nombre
?>

L'appel à srand() n'est pas nécessaire, car PHP le fait automatiquement pour vous. L'initialisation du moteur de nombre aléatoire permet de reproduire des séquences aléatoires ultérieurement. C'est utile pour vérifier qu'un programme se comporte bien comme attendu, dans le cadre de tests, qui doivent être prédictives, mais manipuler des données aléatoires.

Les fonctions rand() peuvent être remplacées par les mêmes fonctionnalités préfixées par mt_. Selon la documentation, mt_rand() utilise une bibliothèque plus légère et moins prédictive que rand(). Dans la pratique, il est parfois difficile de faire la différence sur certaines plate-forme. Sachez donc que cela existe, mais ne basez pas l'optimisation de votre application sur ce préfixe.

Le générateur de nombre aléatoire est assez mal adapté aux tableaux. Certes, on peut utiliser les nombres aléatoires comme index dans le tableau pour extraire des valeurs au hasard, mais il est plus pratique de passer par la fonction array_rand().

Avec un argument, array_rand() retourne un index pris dans les valeurs du tableau. Avec deux arguments, array_rand() retourne un tableau d'index, contenant autant d'éléments que demandé.

 
 
<?php
 
$t = array('a' => 2, 'b' => 3, 'c' => 4);
print array_rand($t)."\n";
 
print_r(array_rand($t,2));
 
?>

Ce script pourrait afficher :

b
Array
(
    [0] => a
    [1] => b
)

array_rand() retourne la liste des clés, ce qui est pratique lorsqu'on doit extraire des données dans un tableau associatif. Mais si le tableau est indexé numériquement, cela fait une étape de plus. Le mieux est de passer par array_flip() pour retourner le tableau : la seule condition à appliquer est que les valeurs soient uniques, sinon, le passage par array_flip() va fausser les quantités.

<?php
 
 
$t = range('a','g');
print_r(array_rand(array_flip($t),2)); // retourne directement un tableau avec 2 lettres et non pas leur index
 
 
$t = array('a','a','a','a','b','c','d');
print_r(array_rand(array_flip($t),2)); // ne retourne jamais de tableau avec 2 'a'
 
 
?>

Enfin, il existe des fonctions mêlantes : leur but est de classer les éléments d'un tableau ou d'une chaîne dans un ordre aléatoire (paradoxal?).

<?php
$t = range('a','f');
shuffle($t);
 
 
print_r($t);
 
 
sort($t);
$c = join('', $t);
print str_shuffle($c);
 
 
?>

Ce script affiche quelque chose comme :
Array
(
    [0] => e
    [1] => b
    [2] => f
    [3] => c
    [4] => a
    [5] => d
)
dfaebc

Cette approche sera plus adaptée pour tirer au sort des éléments dans un groupe, ou établir l'ordre de départ pour une course : avec cette approche, il n'y a pas de doublons (à moins qu'ils soient voulus). Par contre, cette approche est moins intéressante pour les mots de passe, car la non-réutilisation des lettres réduit la robustesse du mot de passe.

A noter
  • Certaines fonctions ont été introduites en PHP 5, voire 5.2.
  • shuffle(), comme sort(), fonctionne sur place, et non pas par valeur de retour
  • On génère des nombres aléatoires, et plus rarement des chaînes littérales. Il faut utiliser un outil de transformation pour passer des nombres aux chiffres

< Précédent   Suivant >

Commentaires

Vous pouvez ajouter votre commentaire!


Vous devez vous connecter pour commenter