2010-06-08 5 views
2

J'ai rencontré un problème étrange sur une installation de serveur WAMP (PHP version 5.3.0, Apache 2.2.11). Lorsque j'utilise sprintf pour générer un nombre, il m'arrive d'obtenir des caractères erronés dans la chaîne de sortie.bug Sprintf avec PHP et Apache dans Windows?

Exemple: (non coupé de tout, c'est le seul code dans le script)

$dt1 = new DateTime('now'); 
$dt2 = new DateTime('now - 10 min'); 

$interval = $dt1->diff($dt2); 

$number = 10.0; 
$string = sprintf("%.1f", $number); 
echo "number: $number, string: $string\n"; 

Si je lance ceci à l'invite de commande avec PHP CLI, je reçois le résultat attendu:

numéro: 10, chaîne: 10,0

Cependant, si je sers à l'aide d'Apache, dans le navigateur je reçois

Numéro

: 10, chaîne:: .0

avec deux points où doit '10' être. (Notez que ':' est le prochain caractère ascii dans la séquence après '9', si $number est 0-9, tout fonctionne.Les nombres supérieurs à 10 semblent utiliser des équivalents ascii - donc 11 est ';', 12 est '<' , etc.)

La partie la plus étrange est que les quatre premières lignes de l'exemple de code ci-dessus semblent affecter les résultats. Logiquement, ces déclarations ne devraient avoir aucun impact, mais si je les commente ou les supprime, le problème disparaît.

Des idées? Quelqu'un d'autre en mesure de reproduire cela?

Notes:

  • J'ai essayé php 5.3.1 et 5.3.2, les deux se comportent de la même façon
  • Le script ci-dessus fonctionne très bien, même dans le navigateur, 5-6 page est actualisée après avoir redémarré Apache. Ensuite, l'erreur, tel que décrit, retourne
+0

est-ce que 'error_reporting' est allumé? Définissez-le sur E_ALL et recherchez les erreurs. – ircmaxell

+0

oui, à la fois 'error_reporting' et' display_errors' sont activés - rien ne s'affiche – potatoe

Répondre

0

Essayez d'ajouter ce au-dessus du code setlocale(LC_ALL, 'en_US');

+0

Bonne pensée, mais malheureusement aucun changement dans les résultats. – potatoe

0

Essayez ceci:

Changement echo "number: $number, string: $string\n"; à:

for ($i = 0, $n = strlen($string); $i < $n; $i++) { 
    echo ord($string[$i]).' '; 
} 

Il vous donnera essentiellement la numérique code de caractère pour chaque octet de la chaîne. Notez que j'ai dit octet. S'il s'agit d'un problème de jeu de caractères ou d'un problème avec les octets de gestion d'Apache, vous devriez le voir ici. La sortie attendue est: 49 48 46 48. Si vous voyez plutôt 58 46 48, alors vous avez peut-être trouvé un bug avec php et devriez soumettre un rapport de bug. Vous devriez également essayer de mettre à jour votre version de php (5.3.2 est dehors) ...

+0

Excellente idée, merci. Je vois en effet "58 46 48" dans le navigateur, mais "49 48 46 48" en ligne de commande (comme prévu, puisque ça a toujours marché là-bas). S'il s'agissait d'un bug php, existe-t-il un mécanisme par lequel il pourrait se manifester uniquement lorsqu'il est exécuté par Apache? – potatoe

+0

Ajoutez un 'var_dump ($ interval);' pour voir ce que l'intervalle donne dans chaque cas. Si c'est différent, alors le problème peut être dans les routines de date. Si c'est identique, essayez de mettre $ interval à cette valeur (par exemple 'float: 10.0' donnerait' $ interval = 10.0') et de voir si vous pouvez reproduire le bug ... – ircmaxell

+0

$ interval a toujours la même valeur, un DateInterval objet dont les champs (y, m, d, h, i, s, inverser, jours) semblent avoir les valeurs correctes. Définir $ interval à toute constante qui évite d'exécuter DateTime :: diff semble résoudre le problème. (DateInterval :: format n'affecte pas le résultat) J'ai mis à jour à PHP 5.3.1 sans changement de résultat, et essayera 5.3.2 suivant. Ce faisant, j'ai appris qu'après le redémarrage d'Apache, la sortie dans le navigateur est correcte pour environ 5-6 rechargements de ce script, après quoi le ':' réapparaît jusqu'au prochain redémarrage d'Apache. – potatoe