From 6c0f34ae7118d5b8804491fbbca2e8ee9dab4f96 Mon Sep 17 00:00:00 2001 From: Fred Tempez Date: Fri, 5 Apr 2024 18:21:09 +0200 Subject: [PATCH] 1.7.09 flock sur le fichier principal (PB sous win) --- core/class/jsondb/JsonDb.class.php | 22 +++--- core/core.php | 107 +++++++++++++++-------------- 2 files changed, 66 insertions(+), 63 deletions(-) diff --git a/core/class/jsondb/JsonDb.class.php b/core/class/jsondb/JsonDb.class.php index eb08a26..6e1c004 100644 --- a/core/class/jsondb/JsonDb.class.php +++ b/core/class/jsondb/JsonDb.class.php @@ -166,38 +166,36 @@ class JsonDb extends \Prowebcraft\Dot error_log('Impossible d\'encoder les données en format JSON.'); return false; } - - $lockFile = $this->db . '.lock'; - $lockHandle = fopen($lockFile, 'w'); + $lockHandle = fopen($this->db, 'r+'); if (flock($lockHandle, LOCK_EX)) { $attempts = 0; $bytesWritten = false; while ($attempts < self::MAX_FILE_WRITE_ATTEMPTS && $bytesWritten === false) { - $bytesWritten = file_put_contents($this->db, $jsonData); + ftruncate($lockHandle, 0); // Vide le fichier + rewind($lockHandle); // Remet le pointeur au début du fichier + $bytesWritten = fwrite($lockHandle, $jsonData); if ($bytesWritten === false) { $attempts++; error_log('Erreur d\'écriture (tentative ' . $attempts . ') : impossible de sauvegarder les données.'); sleep(self::RETRY_DELAY_SECONDS); // Attendre avant de réessayer } } - flock($lockHandle, LOCK_UN); - fclose($lockHandle); - + flock($lockHandle, LOCK_UN); // Libérer le verrouillage + fclose($lockHandle); // Fermer le fichier + if ($bytesWritten === false || $bytesWritten != strlen($jsonData)) { error_log('Erreur d\'écriture, les données n\'ont pas été sauvegardées.'); return false; } } else { error_log('Impossible d\'obtenir un verrouillage sur le fichier de base de données.'); - fclose($lockHandle); + fclose($lockHandle); // Fermer le fichier return false; } - // Supprimer le fichier de verrouillage - if (file_exists($lockFile)) { - unlink($lockFile); - } return true; + + } } \ No newline at end of file diff --git a/core/core.php b/core/core.php index a6e6b25..bd64352 100644 --- a/core/core.php +++ b/core/core.php @@ -792,57 +792,62 @@ class common * * @return bool Retourne true si l'écriture dans le fichier est réussie, false sinon. */ - public static function secureFilePutContents($filename, $data, $options = 0) - { - // Vérifier si l'extension du fichier est JSON - $extension = pathinfo($filename, PATHINFO_EXTENSION); - $encodeJson = strtolower($extension) === 'json'; - - // Tentatives d'encodage JSON si nécessaire - if ($encodeJson) { - $jsonData = null; - $attempts = 0; - while ($attempts < self::MAX_JSON_ENCODE_ATTEMPTS) { - $jsonData = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); - if ($jsonData !== false) { - break; // Sortir de la boucle si l'encodage réussit - } - $attempts++; - error_log('Erreur d\'encodage JSON (tentative ' . $attempts . ') : ' . json_last_error_msg()); - sleep(self::RETRY_DELAY_SECONDS); // Attendre avant de réessayer - } - - if ($jsonData === false) { - error_log('Impossible d\'encoder les données en format JSON.'); - return false; - } - } else { - // Pas d'encodage JSON nécessaire - $jsonData = $data; - } - - // Écriture sécurisée dans le fichier avec un verrouillage - $attempts = 0; - while ($attempts < self::MAX_FILE_WRITE_ATTEMPTS) { - $lockHandle = fopen($filename . '.lock', 'w'); - if (flock($lockHandle, LOCK_EX)) { - $bytesWritten = file_put_contents($filename, $jsonData, $options); - flock($lockHandle, LOCK_UN); - fclose($lockHandle); - if ($bytesWritten !== false && $bytesWritten === strlen($jsonData)) { - return true; // Écriture réussie - } - } else { - fclose($lockHandle); - } - $attempts++; - error_log('Erreur d\'écriture (tentative ' . $attempts . ') : impossible de sauvegarder les données dans ' . $filename); - sleep(self::RETRY_DELAY_SECONDS); // Attendre avant de réessayer - } - - error_log('Impossible d\'écrire dans le fichier ' . $filename . ' après ' . self::MAX_FILE_WRITE_ATTEMPTS . ' tentatives.'); - return false; - } + public static function secureFilePutContents($filename, $data, $options = 0) + { + // Vérifier si l'extension du fichier est JSON + $extension = pathinfo($filename, PATHINFO_EXTENSION); + $encodeJson = strtolower($extension) === 'json'; + + // Tentatives d'encodage JSON si nécessaire + if ($encodeJson) { + $jsonData = null; + $attempts = 0; + while ($attempts < self::MAX_JSON_ENCODE_ATTEMPTS) { + $jsonData = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); + if ($jsonData !== false) { + break; // Sortir de la boucle si l'encodage réussit + } + $attempts++; + error_log('Erreur d\'encodage JSON (tentative ' . $attempts . ') : ' . json_last_error_msg()); + sleep(self::RETRY_DELAY_SECONDS); // Attendre avant de réessayer + } + + if ($jsonData === false) { + error_log('Impossible d\'encoder les données en format JSON.'); + return false; + } + } else { + // Pas d'encodage JSON nécessaire + $jsonData = $data; + } + + // Écriture sécurisée dans le fichier avec un verrouillage + $attempts = 0; + while ($attempts < self::MAX_FILE_WRITE_ATTEMPTS) { + $lockHandle = fopen($filename, 'c+'); + if ($lockHandle !== false && flock($lockHandle, LOCK_EX)) { + $bytesWritten = fwrite($lockHandle, $jsonData); + if ($bytesWritten !== false && $bytesWritten === strlen($jsonData)) { + fflush($lockHandle); // Vider le tampon + ftruncate($lockHandle, ftell($lockHandle)); // Tronquer le fichier à la position actuelle du pointeur + flock($lockHandle, LOCK_UN); // Libérer le verrouillage + fclose($lockHandle); // Fermer le fichier + return file_put_contents($filename, $jsonData, $options) !== false; // Écriture réussie + } + flock($lockHandle, LOCK_UN); // Libérer le verrouillage en cas d'échec d'écriture + } + if ($lockHandle !== false) { + fclose($lockHandle); // Fermer le fichier en cas d'échec d'acquisition du verrouillage + } + $attempts++; + error_log('Erreur d\'écriture (tentative ' . $attempts . ') : impossible de sauvegarder les données dans ' . $filename); + sleep(self::RETRY_DELAY_SECONDS); // Attendre avant de réessayer + } + + error_log('Impossible d\'écrire dans le fichier ' . $filename . ' après ' . self::MAX_FILE_WRITE_ATTEMPTS . ' tentatives.'); + return false; + } +