J'ai le code suivant qui enregistre du code php dans un fichier, puis le charge et l'exécute à nouveau et parfois la méthode require renvoie un int, pourquoi cela se produit-il ?
Comment reproduire ?
Utilisez deux processus php pour exécuter le code ci-dessus
php demo.php
Voici la documentation de
require
的标准行为,与include
, le comportement est le même entre les deux :Comme vous pouvez le voir, lorsque la valeur de retour n'est pas écrasée, un entier (1) est renvoyé sur le chemin heureux.
Cela a du sens pour votre exemple, jusqu'à présent le fichier existe (donc pas d'erreur fatale), mais comme le fichier vient d'être créé, il se peut qu'il soit simplement tronqué, c'est-à-dire qu'il est vide. p>
Ainsi, la valeur de retour n'est pas écrasée et vous pouvez voir le int(1).
Une autre explication est naturellement que vous avez écrasé avec des nombres entiers, ce qui est également possible puisque plusieurs processus peuvent écrire dans le même fichier, mais avec la façon dont vous avez écrit votre exemple, c'est moins probable. Je le mentionne seulement parce que c'est une autre explication valable.
contient si présent
Exemple comment suspendre une condition de concurrence critique lorsque vous recherchez
$result
au lieu de (uniquement) lorsque le fichier existe :L'idée derrière cela est que nous faisons très peu de gestion des erreurs, comme vérifier si le fichier existe, sinon il ne peut pas être inclus (include() émet simplement un avertissement et le transmet avec $result = false), et ensuite si $ le résultat est chargé, il le fait. S'applique aux tests is_array().
C'est ce que nous avons pour les erreurs, mais nous savons ce que nous recherchons, c'est-à-dire que $result est un tableau.
C'est ce qu'on appelle souvent une transaction ou une opération de transaction.
Dans ce nouvel exemple, nous n'entrons même pas le if-body lorsque le tableau $result est vide, c'est-à-dire qu'il ne contient aucune donnée.
Au niveau du traitement du programme, qui pourrait nous intéresser, la présence ou l'absence d'un fichier, être vide ou non, ou même être mal écrit sont autant de conditions d'erreur qui doivent être "mangées" et invalider le $result.
L'erreur de définition n'existe pas.
Gestion des erreurs d'analyse (pour Include-If-Exists)
Depuis PHP 7.0, nous pouvons utiliser include() et si malheureusement le fichier include renvoyé est à moitié écrit, nous verrons une erreur d'analyse PHP qui peut êtreattrapée:
Veuillez vous référer àPHP try-catch-finallypour savoir comment lancer des exceptions/travail de gestion des exceptions en détail, assert() est utilisé pour enregistrer la signification du paramètre d'entrée $cachePath dans l'exemple.
Le deuxième exemple n'utilise pas l'opération de suppression "@", la raison est que si vous l'utilisez comme l'exemple précédent, et que le fichier à inclure contiendra une véritable erreur fatale, l'erreur fatale sera réduite au silence. De nos jours, dans PHP moderne, ce n'est plus un gros problème, mais utiliser file_exists() + include() - bien qu'il existe une condition de concurrence due au temps de vérification par rapport au temps d'utilisation - est sûr (seulement un avertissement) pour les fichiers inexistants. et les erreurs fatales ne sont pas cachées.
Comme vous l'avez peut-être vu, plus vous connaissez de détails, plus il est difficile d'écrire un code aussi évolutif que possible. Nous ne devons pas nous perdre dans la gestion des erreurs elle-même, mais nous concentrer sur les résultats et définir que ces erreurs n'existent pas.
Cela dit, include() provoque toujours le chargement des données en mémoire, file_exists() n'est utilisé que pour "supprimer" les avertissements, nous savons que, néanmoins, include() peut émettre des avertissements et renvoyer un entier au lieu d'un tableau .
Maintenant, puisque la programmation est difficile : vous pouvez alors l'enrouler en boucle et dire de réessayer trois fois. Pourquoi ne pas utiliser uneboucle forpour compter et protéger les tentatives numériques ?
Ce problème ne peut pas être reproduit si le script n'a toujours qu'un seul exécuteur.
Si vous parlez d'exécuter ce script en parallèle, le problème est que l'écriture du fichier en mode exclusif ne vous protège pas de la lecture du fichier ultérieurement pendant le processus d'écriture.
Le processus peut écrire dans le fichier (et posséder le verrou), mais
require
ne pas honorer le verrou (les verrous du système de fichiers sont consultatifs et non appliqués).La bonne solution est donc :