J'aime avoir raison, et je vais prouver que j'ai raison sur ce cas. Bien sûr, je prends un cas extrême, volontairement pour pousser PHP dans ces retranchement :
<?php
for($i=0;$i < 100000;$i++)
{
$fp = fopen('counter', 'r+') ;
if(!$fp) break ;
$count = (integer) fread($fp,15) ;
var_dump($count) ;
++$count ;
fseek($fp, 0) ;
fwrite($fp, (string)$count) ;
flush($fp) ;
fclose($fp) ;
}
var_dump($count) ;
?>
J'ai lancé six connexions concurrentes sur le même script (même URL). Si PHP attendait la libération du fichier pour écrire dedant, le nombre finale devrait être 6.000.000.
La chaîne contenue dans le fichier counter est : 1147673. Cette valeur n'a aucune signification, si ce n'est qu'on est bien au dessus 600.000 attendus.
Si l'on observe le contenu du fichier counter, on s'aperçoit que le contenu est complètement délirant, pouvant régresser violemment à une valeur franchement inférieure.
Avec le même source, mais en rajoutant :
flock($fp, LOCK_EX + LOCK_SH) ;
on obtient : 494271.
En consultant la documentation de
flock, on s'aperçoit que les applications Web ne sont pas bien codées, ne sont pas correctement portable car flock est obligatoire sous les Microsoft Windows de la branche NT.
Alors maintenant, ma démarche est peut-être erronée, mais j'aimerais qu'on me le prouve ;)
Ce test prouve simplement qu'il n'est pas pertinent de stocker une information issue de sources concurrentes directement dans un fichier.
Je soupçonne le système d'exploitation de tromper PHP lors de l'accès au fichier.
Il faudrait faire le même essai avec MySQL tient.
Le test a été effectué depuis une machine en ADSL vers un serveur dédié Apache2/PHP5, 512 Mo RAM, Athlon XP 2400.
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.