Bonjour
J'ai un petit soucis avec la fonction file_put_contents.
Je m'explique :
Voici un code :
Code :
- $data = array('a'=>rand(),'b'=>rand(),'c'=>rand());
- file_put_contents($filename,json_encode($data), LOCK_EX);
|
Ce qui se passe, c'est que parfois (relativement rarement néanmoins), ce qui est écrit dans le fichier n'est pas correct (typiquement j'ai deux accolades fermantes, comme si le contenu précédent n'était pas effacé)
J'ai pensé à un problème d'écritures simultanées, mais le problème est que ce fichier ne peut être écrit que par cette fonction et que cette fonction ne peut être appelée deux fois en même temps. (néanmoins je peux avoir une lecture (via une fonction appelée par un autre client) et une écriture via cette fonction en simultané)
Auriez vous une idée du problème (ou de comment le résoudre ?)
Merci d'avance !
EDIT :
Je n'ai toujours pas résolu le problème
Après quelques tests, j'ai néanmoins remarqué le soucis suivant :
Voilà deux scripts php queje fais tourner en même temps :
Code :
- <?php
- // Fichier "ecriture.php"
- set_time_limit(0);
- ignore_user_abort(true);
- $filename = 'test.json';
- $puiss = array();
- for($i=0;$i<10;$i++){
- $puiss[$i]=pow(10,$i+1);
- }
- for ($i = 0; $i < 100000; $i++) {
- $data = array('a' => (mt_rand()%$puiss[rand()%10]), 'b' => (mt_rand()%$puiss[rand()%10]), 'c' => (mt_rand()%$puiss[rand()%10]));
- file_put_contents($filename, json_encode($data), LOCK_EX);
- }
- echo 'fini';
- ?>
|
Code :
- <?php
- // Fichier lecture.php
- set_time_limit(0);
- ignore_user_abort(true);
- $filename = 'test.json';
- for ($i = 0; $i < 1000000; $i++) {
- $data = file_get_contents($filename);
- if (json_decode($data, true) == false) {
- echo 'Erreur !! - "'.$data.'"';
- break;
- }
- }
- echo 'fini';
- ?>
|
Donc je fais tourner les deux en même temps et le script lecture et le script lecture s'arrête quasi immédiatement, me montrant la chaine de caractère vide ...
Alors que selon moi, le LOCK_EX aurait du empêcher cela !
EDIT EDIT : en rajoutant : " && strlen($data)!=0) et en faisant tourner ces deux scripts en parallèle, j'ai obtenu
Code :
- {"a":71395911,"b":8808,"c":17}6}
|
, ce code permet donc de reproduire le bug
Message édité par nisalon_caje le 10-01-2012 à 23:56:16