SafeStream : accès sécurisé aux fichiers
Nette SafeStream garantit que chaque lecture et écriture de fichier se déroule de manière isolée. Cela signifie qu'aucun thread ne commencera à lire un fichier qui n'est pas encore entièrement écrit, ou que plusieurs threads ne réécriront pas le même fichier.
Installation :
composer require nette/safe-stream
À quoi ça sert ?
À quoi servent réellement les opérations isolées ? Commençons par un exemple simple qui écrit de manière répétée dans un fichier puis lit la même chaîne à partir de celui-ci :
$s = str_repeat('Long String', 10000);
$counter = 1000;
while ($counter--) {
file_put_contents('fichier', $s); // l'écrire
$readed = file_get_contents('fichier'); // le lire
if ($s !== $readed) { // le vérifier
echo 'les chaînes diffèrent !';
}
}
On pourrait penser que l'appel echo 'les chaînes diffèrent !'
ne peut jamais se produire, mais c'est le
contraire qui est vrai. Essayez d'exécuter ce script dans deux onglets de navigateur en même temps. L'erreur se produira
pratiquement immédiatement.
L'un des onglets lira en effet le fichier au moment où l'autre n'aura pas encore fini de l'écrire entièrement, de sorte que le contenu ne sera pas complet.
Le code ci-dessus n'est donc pas sûr s'il est exécuté plusieurs fois en même temps (c'est-à-dire dans plusieurs threads). Ce qui n'est pas inhabituel sur Internet, souvent un serveur répond à un grand nombre d'utilisateurs en même temps. Il est donc très important de s'assurer que votre application fonctionne de manière fiable même lorsqu'elle est exécutée dans plusieurs threads (thread-safe). Sinon, des pertes de données et des erreurs difficiles à détecter se produiront.
Mais comme vous pouvez le voir, les fonctions natives PHP pour la lecture et l'écriture de fichiers ne sont pas isolées et atomiques.
Comment utiliser SafeStream ?
SafeStream crée un protocole sécurisé permettant de lire et d'écrire des fichiers de manière isolée à l'aide des
fonctions PHP standard. Il suffit d'ajouter nette.safe://
avant le nom du fichier :
file_put_contents('nette.safe://fichier', $s);
$s = file_get_contents('nette.safe://fichier');
SafeStream garantit qu'à un instant donné, un seul thread au maximum peut écrire dans le fichier. Les autres threads attendent dans la file d'attente. Si aucun thread n'écrit, n'importe quel nombre de threads peut lire le fichier en parallèle.
Toutes les fonctions PHP courantes peuvent être utilisées avec le protocole, par exemple :
// 'r' signifie ouvrir uniquement en lecture
$handle = fopen('nette.safe://file.txt', 'r');
$ini = parse_ini_file('nette.safe://translations.neon');