Pourquoi require_once est-il si mauvais à utiliser?


143

Tout ce que j'ai lu sur les meilleures pratiques de codage PHP me dit de ne pas utiliser à require_oncecause de la vitesse.

Pourquoi est-ce?

Quelle est la bonne / meilleure façon de faire la même chose que require_once? Si cela compte, j'utilise PHP 5.


9
Cette question est assez ancienne maintenant, et les réponses sont douteuses plus pertinentes. Ce serait formidable de voir un ensemble mis à jour de réponses des participants :)
Purefan

Réponses:


108

require_onceet les include_oncedeux exigent que le système garde un journal de ce qui a déjà été inclus / requis. Chaque *_onceappel signifie vérifier ce journal. Il y a donc certainement un travail supplémentaire en cours, mais suffisamment pour nuire à la vitesse de l'ensemble de l'application?

... J'en doute vraiment ... Sauf si vous utilisez du matériel vraiment ancien ou que vous le faites beaucoup .

Si vous êtes en train de faire des milliers de *_once, vous pouvez faire le travail vous - même d'une façon plus légère. Pour des applications simples, tout en vous assurant que vous avez seulement inclus une fois devrait suffire , mais si vous obtenez toujours des erreurs de Redéfinir, vous pourriez quelque chose comme ceci:

if (!defined('MyIncludeName')) {
    require('MyIncludeName');
    define('MyIncludeName', 1);
}

Je m'en tiendrai personnellement aux *_oncedéclarations, mais sur un benchmark stupide d'un million de passes, vous pouvez voir une différence entre les deux:

                php                  hhvm
if defined      0.18587779998779     0.046600103378296
require_once    1.2219581604004      3.2908599376678

10-100 × plus lent avec require_onceet il est curieux que cela require_oncesoit apparemment plus lent hhvm. Encore une fois, cela n'est pertinent pour votre code que si vous exécutez des *_oncemilliers de fois.


<?php // test.php

$LIMIT = 1000000;

$start = microtime(true);

for ($i=0; $i<$LIMIT; $i++)
    if (!defined('include.php')) {
        require('include.php');
        define('include.php', 1);
    }

$mid = microtime(true);

for ($i=0; $i<$LIMIT; $i++)
    require_once('include.php');

$end = microtime(true);

printf("if defined\t%s\nrequire_once\t%s\n", $mid-$start, $end-$mid);

<?php // include.php

// do nothing.

29
Je doute que votre méthode defined () soit plus rapide que la table de recherche intégrée, mais je suis d'accord avec votre point de vue général - sûrement un non-problème?!
Bobby Jack

1
Je suis assez sûr que vous avez raison Bobby mais je ne préconise pas les définitions sur _une fois. C'est juste une option. Le temps qu'il faudrait pour interpréter le code pourrait même le ralentir légèrement, mais cela dit, je ne sais pas à quel point la méthode interne est approfondie. Cela pourrait faire un travail supplémentaire pour éviter les doublons.
Oli

8
L'autre inconvénient est qu'APC ne met pas en cache include_once et require_once appelle IIRC
dcousineau

3
J'ai juste fait un test très basique des deux méthodes - j'ai fait 1 000 000 itérations, y compris un fichier qui définissait simplement une constante «testinclude» à true. Dans le premier test, j'ai utilisé require_once, le second j'ai utilisé if (! Defined ('testinclude')) et les résultats étaient intéressants: Require: 0.81639003753662 Non défini: 0.17906713485718 Défini est 0.63732290267944 microsecondes plus rapide.
Travis Weston

Le cas avec define sera plus rapide puisque vous n'effectuez aucun type de vérification supplémentaire comme l'utilisation de realpath. Il ne s'agit pas de comparer deux choses qui sont vraiment identiques.
jgmjgm

150

Ce fil me fait grincer des dents, car il y a déjà eu une "solution publiée", et c'est, à toutes fins utiles, faux. Énumérons:

  1. Les définitions sont vraiment chères en PHP. Vous pouvez le rechercher ou le tester vous-même, mais le seul moyen efficace de définir une constante globale en PHP est via une extension. (Les constantes de classe sont en fait assez bonnes en termes de performances, mais c'est un point discutable, à cause de 2)

  2. Si vous utilisez require_once()correctement, c'est-à-dire pour l'inclusion de classes, vous n'avez même pas besoin de définir; il suffit de vérifier si class_exists('Classname'). Si le fichier que vous incluez contient du code, c'est-à-dire que vous l'utilisez de manière procédurale, il n'y a absolument aucune raison qui require_once()devrait être nécessaire pour vous; à chaque fois que vous incluez le fichier que vous supposez faire un appel de sous-programme.

Donc, pendant un certain temps, beaucoup de gens ont utilisé la class_exists()méthode pour leurs inclusions. Je n'aime pas ça parce que c'est déroutant, mais ils avaient de bonnes raisons de le faire: require_once()c'était assez inefficace avant certaines des versions les plus récentes de PHP. Mais cela a été corrigé, et je soutiens que le bytecode supplémentaire que vous auriez à compiler pour le conditionnel, et l'appel de méthode supplémentaire, l'emporteraient de loin sur toute vérification interne de la table de hachage.

Maintenant, un aveu: ce truc est difficile à tester, car il ne représente que si peu de temps d'exécution.

Voici la question à laquelle vous devriez réfléchir: les inclusions, en règle générale, sont chères en PHP, car chaque fois que l'interpréteur en frappe un, il doit repasser en mode d'analyse, générer les opcodes, puis revenir en arrière. Si vous avez plus de 100 inclusions, cela aura certainement un impact sur les performances. La raison pour laquelle l'utilisation ou non de require_once est une question si importante est que cela rend la vie difficile pour les caches d'opcode. Une explication à cela peut être trouvée ici, mais cela se résume à ceci:

  • Si pendant l'analyse, vous savez exactement de quels fichiers d'inclusion vous aurez besoin pendant toute la durée de vie de la requête, require()ceux du tout début et le cache d'opcode gérera tout le reste pour vous.

  • Si vous n'exécutez pas de cache opcode, vous êtes dans une situation difficile. L'intégration de toutes vos inclusions dans un seul fichier (ne le faites pas pendant le développement, uniquement en production) peut certainement aider à analyser le temps, mais c'est difficile à faire, et aussi, vous devez savoir exactement ce que vous allez inclure pendant le demande.

  • Le chargement automatique est très pratique, mais lent, car la logique de chargement automatique doit être exécutée chaque fois qu'une inclusion est effectuée. En pratique, j'ai constaté que le chargement automatique de plusieurs fichiers spécialisés pour une demande ne posait pas trop de problème, mais vous ne devriez pas charger automatiquement tous les fichiers dont vous aurez besoin.

  • Si vous avez peut-être 10 inclus (c'est un calcul très arrière du calcul de l'enveloppe), tout ce branlage n'en vaut pas la peine: optimisez simplement vos requêtes de base de données ou quelque chose du genre.


14
C'est 4 ans et pour la plupart ne s'applique plus define(), require_once()et defined()tous prennent environ 1 à 2 microsecondes chacun sur ma machine.
Daniel Beardsley

72
Mais c'est 2 microsecondes plus tôt que l'utilisateur aurait la page. Plus d'un an de pages vues, cela pourrait faire gagner 3 secondes à l'utilisateur! Ils pourraient regarder un dixième d'une publicité pendant cette période! Pensez à l'utilisateur. Ne perdez pas de microsecondes.
Andrew Ensley

15
Juste pour que tout le monde prenne conscience du sarcasme, une microseconde équivaut à 1/1000000 de seconde.
Andy Chase

1
@AndrewEnsley Vous vous trompez simplement avec tout votre sarcasme. Vous ignorez le fait que PHP fonctionne également sur des microprocesseurs, 1 microseconde sur votre PC équivaut à plusieurs millisecondes sur un microprocesseur. Maintenant, qu'en est-il d'avoir 20 fichiers d'inclusion, un projet plus important? C'est 20 fois plusieurs millisecondes de retard introduit, donc nous atteignons déjà un point qui est perceptible pour un humain. Si ce script est appelé fréquemment, cela entraînera des problèmes de performances sur le système. L'optimisation n'est pas une blague et le monde entier ne tourne pas autour de votre PC. Il y a dix milliers de processeurs en cours d'utilisation.
John

2
@John. C'était une blague faite de bonne humeur. Aucune malice intentionnelle. Si cela vaut la peine pour vous d'optimiser vos inclusions, allez-y.
Andrew Ensley

66

Je suis devenu curieux et j'ai vérifié le lien d'Adam Backstrom vers Tech Your Universe . Cet article décrit l'une des raisons pour lesquelles require doit être utilisé au lieu de require_once. Cependant, leurs affirmations ne tiennent pas compte de mon analyse. Je serais intéressé de voir où j'ai peut-être mal analysé la solution. J'ai utilisé PHP 5.2.0 pour les comparaisons.

J'ai commencé par créer 100 fichiers d'en-tête qui utilisaient require_once pour inclure un autre fichier d'en-tête. Chacun de ces fichiers ressemblait à quelque chose comme:

<?php
    // /home/fbarnes/phpperf/hdr0.php
    require_once "../phpperf/common_hdr.php";

?>

J'ai créé ceux-ci en utilisant un hack rapide Bash:

for i in /home/fbarnes/phpperf/hdr{00..99}.php; do
    echo "<?php
    // $i" > $i
    cat helper.php >> $i;
done

De cette façon, je pourrais facilement permuter entre l'utilisation de require_once et de require lors de l'inclusion des fichiers d'en-tête. J'ai ensuite créé un app.php pour charger les cent fichiers. Cela ressemblait à:

<?php
    // Load all of the php hdrs that were created previously
    for($i=0; $i < 100; $i++)
    {
        require_once "/home/fbarnes/phpperf/hdr$i.php";
    }

    // Read the /proc file system to get some simple stats
    $pid = getmypid();
    $fp = fopen("/proc/$pid/stat", "r");
    $line = fread($fp, 2048);
    $array = split(" ", $line);

    // Write out the statistics; on RedHat 4.5 with kernel 2.6.9
    // 14 is user jiffies; 15 is system jiffies
    $cntr = 0;
    foreach($array as $elem)
    {
        $cntr++;
        echo "stat[$cntr]: $elem\n";
    }
    fclose($fp);
?>

J'ai comparé les en-têtes require_once avec des en-têtes require qui utilisaient un fichier d'en-tête ressemblant à:

<?php
    // /home/fbarnes/phpperf/h/hdr0.php
    if(!defined('CommonHdr'))
    {
        require "../phpperf/common_hdr.php";
        define('CommonHdr', 1);
    }
?>

Je n'ai pas trouvé beaucoup de différence lors de l'exécution avec require et require_once. En fait, mes tests initiaux semblaient impliquer que require_once était légèrement plus rapide, mais je ne le crois pas nécessairement. J'ai répété l'expérience avec 10000 fichiers d'entrée. Ici, j'ai vu une différence cohérente. J'ai exécuté le test plusieurs fois, les résultats sont proches mais l'utilisation de require_once utilise en moyenne 30,8 jiffies utilisateur et 72,6 jiffies système; l'utilisation de require utilise en moyenne 39,4 jiffies utilisateur et 72,0 jiffies système. Par conséquent, il semble que la charge soit légèrement inférieure en utilisant require_once. Cependant, l'heure de l'horloge murale est légèrement augmentée. Les 10 000 appels require_once utilisent en moyenne 10,15 secondes et 10 000 appels nécessitent 9,84 secondes en moyenne.

L'étape suivante consiste à examiner ces différences. J'ai utilisé strace pour analyser les appels système en cours.

Avant d'ouvrir un fichier depuis require_once, les appels système suivants sont effectués:

time(NULL)                              = 1223772434
lstat64("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes/phpperf", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes/phpperf/h", {st_mode=S_IFDIR|0755, st_size=270336, ...}) = 0
lstat64("/home/fbarnes/phpperf/h/hdr0.php", {st_mode=S_IFREG|0644, st_size=88, ...}) = 0
time(NULL)                              = 1223772434
open("/home/fbarnes/phpperf/h/hdr0.php", O_RDONLY) = 3

Cela contraste avec exiger:

time(NULL)                              = 1223772905
lstat64("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes/phpperf", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes/phpperf/h", {st_mode=S_IFDIR|0755, st_size=270336, ...}) = 0
lstat64("/home/fbarnes/phpperf/h/hdr0.php", {st_mode=S_IFREG|0644, st_size=146, ...}) = 0
time(NULL)                              = 1223772905
open("/home/fbarnes/phpperf/h/hdr0.php", O_RDONLY) = 3

Tech Your Universe implique que require_once devrait faire plus d'appels lstat64. Cependant, ils effectuent tous les deux le même nombre d'appels lstat64. La différence est peut-être que je n'utilise pas APC pour optimiser le code ci-dessus. Cependant, j'ai ensuite comparé la sortie de strace pour toutes les exécutions:

[fbarnes@myhost phpperf]$ wc -l strace_1000r.out strace_1000ro.out
  190709 strace_1000r.out
  210707 strace_1000ro.out
  401416 total

En fait, il y a environ deux appels système supplémentaires par fichier d'en-tête lors de l'utilisation de require_once. Une différence est que require_once a un appel supplémentaire à la fonction time ():

[fbarnes@myhost phpperf]$ grep -c time strace_1000r.out strace_1000ro.out
strace_1000r.out:20009
strace_1000ro.out:30008

L'autre appel système est getcwd ():

[fbarnes@myhost phpperf]$ grep -c getcwd strace_1000r.out strace_1000ro.out
strace_1000r.out:5
strace_1000ro.out:10004

Ceci est appelé parce que j'ai décidé du chemin relatif référencé dans les fichiers hdrXXX. Si j'en fais une référence absolue, la seule différence est l'appel de temps supplémentaire (NULL) effectué dans le code:

[fbarnes@myhost phpperf]$ wc -l strace_1000r.out strace_1000ro.out
  190705 strace_1000r.out
  200705 strace_1000ro.out
  391410 total
[fbarnes@myhost phpperf]$ grep -c time strace_1000r.out strace_1000ro.out
strace_1000r.out:20008
strace_1000ro.out:30008

Cela semble impliquer que vous pouvez réduire le nombre d'appels système en utilisant des chemins absolus plutôt que des chemins relatifs. La seule différence en dehors de cela est les appels de temps (NULL) qui semblent être utilisés pour instrumenter le code pour comparer ce qui est plus rapide.

Une autre note est que le package d'optimisation APC a une option appelée "apc.include_once_override" qui prétend réduire le nombre d'appels système effectués par les appels require_once et include_once (voir la documentation PHP ).


6
Et toute "optimisation" que vous devez exécuter 10 000 fois pour voir une différence aussi minuscule ne mérite même pas de s'inquiéter. Utilisez un profileur et découvrez où se trouvent les véritables goulots d'étranglement dans votre application. Je doute que cette question soit le goulot d'étranglement.
DGM

1
Tout cela signifie que cela n'a aucune importance. Utilisez ce qui fonctionne le mieux pour vous logiquement.
Buttle Butkus

wat are jiffies
OverCoder

21

Pouvez-vous nous donner des liens vers ces pratiques de codage qui disent de l'éviter? En ce qui me concerne, c'est un non-problème complet . Je n'ai pas regardé le code source moi-même, mais j'imagine que la seule différence entre includeet include_onceest que cela include_onceajoute ce nom de fichier à un tableau et vérifie le tableau à chaque fois. Il serait facile de garder ce tableau trié, donc la recherche devrait être O (log n), et même une application de taille moyenne n'aurait que quelques douzaines d'inclusions.


l'un est, chazzuka.com/blog/?p=163 ils n'ont vraiment pas «ne pas», mais trop de choses «coûteuses» s'additionnent. et en fait, tous les fichiers inclus / requis sont ajoutés à un tableau interne (il y a une fonction pour le retourner), je suppose que les _once doivent boucler ce tableau et faire strcmp, ce qui s'additionnerait
Uberfuzzy

7

Une meilleure façon de faire les choses est d'utiliser une approche orientée objet et d'utiliser __autoload () .


3
mais le tout premier exemple dans la page des objets de chargement automatique que vous avez lié à utilise require_once
Shabbyrobe

Je n'achète pas ça. Il y a BEAUCOUP de situations dans lesquelles OO ne correspond pas aussi bien que d'autres paradigmes, donc vous ne devriez pas le forcer juste à gagner les petits avantages qu'il peut y avoir avec __autoload ().
Bobby Jack

1
vous penseriez que le chargement automatique prendrait en fait plus de temps que * _une (en supposant que vous n'avez besoin que de ce dont vous avez besoin).
nickf

Non, ce n'est pas le cas, du moins pas définitivement, le chargement automatique doit toujours être inclus d'une manière ou d'une autre et c'est un dernier recours pour PHP avant l'échec de l'erreur - donc en réalité, PHP effectue des vérifications potentiellement inutiles à travers tous les endroits qui s'appliqueraient à inclure / exiger et APRÈS QU'il appellerait autoload (s'il y en a un défini) ... PS: __autoload()est déconseillé et il pourrait être obsolète à l'avenir, vous devriez utiliser spl_autoload_register(...)ces jours-ci ... PS2: ne vous méprenez pas, j'utilise parfois la fonctionnalité de chargement automatique; )
jave.web

6

Ce n'est pas l'utilisation de la fonction qui est mauvaise. C'est une mauvaise compréhension de comment et quand l'utiliser, dans une base de code globale. Je vais juste ajouter un peu plus de contexte à cette notion peut-être mal comprise:

Les gens ne devraient pas penser que require_once est une fonction lente. Vous devez inclure votre code d'une manière ou d'une autre. require_once()vs require()la vitesse n'est pas le problème. Il s'agit de la performance qui entrave les mises en garde qui peuvent résulter de son utilisation aveugle. S'il est utilisé largement sans tenir compte du contexte, il peut entraîner un énorme gaspillage de mémoire ou un gaspillage de code.

Ce que j'ai vu qui est vraiment mauvais, c'est quand d'énormes frameworks monolithiques sont utilisés require_once()de toutes les mauvaises manières, en particulier dans un environnement complexe orienté objet (OO).

Prenons l'exemple de l'utilisation require_once()en haut de chaque classe comme on le voit dans de nombreuses bibliothèques:

require_once("includes/usergroups.php");
require_once("includes/permissions.php");
require_once("includes/revisions.php");
class User{
  // User functions
}

La Userclasse est donc conçue pour utiliser les trois autres classes. C'est suffisant!

Mais maintenant, que se passe-t-il si un visiteur navigue sur le site et n'est même pas connecté et que le framework se charge: require_once("includes/user.php");pour chaque demande.

Il comprend 1 + 3 classes inutiles qu'il n'utilisera jamais lors de cette demande particulière. C'est ainsi que les frameworks gonflés finissent par utiliser 40 Mo par requête au lieu de 5 Mo ou moins.


Les autres façons dont il peut être mal utilisé, c'est lorsqu'une classe est réutilisée par beaucoup d'autres! Disons que vous avez environ 50 classes qui utilisent des helperfonctions. Pour vous assurer que helpersces classes sont disponibles lors de leur chargement, vous obtenez:

require_once("includes/helpers.php");
class MyClass{
  // Helper::functions(); // etc..
}

Il n'y a rien de mal ici en soi. Cependant, si une demande de page inclut 15 classes similaires. Vous exécutez require_once15 fois, ou pour un joli visuel:

require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");

L'utilisation de require_once () affecte techniquement les performances pour exécuter cette fonction 14 fois, en plus d'avoir à analyser ces lignes inutiles. Avec seulement 10 autres classes très utilisées avec ce problème similaire, cela pourrait représenter plus de 100 lignes d'un tel code répétitif plutôt inutile.

Avec cela, cela vaut probablement la peine d'être utilisé require("includes/helpers.php");au démarrage de votre application ou de votre framework. Mais comme tout est relatif, tout dépend si le poids par rapport à la fréquence d'utilisation de la helpersclasse vaut la peine d'économiser 15 à 100 lignes require_once(). Mais si la probabilité de ne pas utiliser le helpersfichier sur une demande donnée est nulle, alors requiredevrait certainement être dans votre classe principale à la place. Avoir require_oncedans chaque classe séparément devient un gaspillage de ressources.


La require_oncefonction est utile lorsque cela est nécessaire, mais elle ne doit pas être considérée comme une solution monolithique à utiliser partout pour charger toutes les classes.


5

Le wiki PEAR2 (quand il existait) avait l'habitude de lister les bonnes raisons d'abandonner toutes les directives require / include en faveur du chargement automatique , au moins pour le code de la bibliothèque. Celles-ci vous attachent à des structures de répertoires rigides lorsque des modèles d'emballage alternatifs comme phar sont à l'horizon.

Mise à jour: Comme la version Web archivée du wiki est horriblement moche, j'ai copié les raisons les plus convaincantes ci-dessous:

  • include_path est requis pour utiliser un package (PEAR). Cela rend difficile de regrouper un package PEAR dans une autre application avec son propre include_path, de créer un seul fichier contenant les classes nécessaires, de déplacer un package PEAR vers une archive phar sans modification importante du code source.
  • lorsque le niveau supérieur require_once est mélangé avec un require_once conditionnel, cela peut entraîner un code qui ne peut pas être mis en cache par des caches d'opcode tels que APC, qui sera fourni avec PHP 6.
  • relative require_once nécessite que include_path soit déjà configuré à la valeur correcte, ce qui rend impossible l'utilisation d'un package sans include_path approprié

5

Les *_once()fonctions indiquent chaque répertoire parent pour garantir que le fichier que vous incluez n'est pas le même que celui qui a déjà été inclus. C'est en partie la raison du ralentissement.

Je recommande d'utiliser un outil comme Siege pour l'analyse comparative. Vous pouvez essayer toutes les méthodologies suggérées et comparer les temps de réponse.

Plus sur le sujet require_once()est à Tech Your Universe .


Merci pour le pointeur vers l'article. require_once () est une bonne ceinture de sécurité sur les fichiers à double inclusion, et nous continuerons à l'utiliser, mais être capable de le rendre propre est bien.
Andy Lester

2

Même si require_onceet include_once sont plus lents que requireet include(ou quelles que soient les alternatives), nous parlons ici du plus petit niveau de micro-optimisation. Votre temps est bien mieux dépensé pour optimiser cette boucle ou requête de base de données mal écrite que de vous soucier de quelque chose comme require_once.

Maintenant, on pourrait faire un argument en disant que cela require_oncepermet de mauvaises pratiques de codage parce que vous n'avez pas besoin de faire attention à garder vos inclusions propres et organisées, mais cela n'a rien à voir avec la fonction elle - même et surtout pas sa vitesse.

Évidemment, le chargement automatique est préférable pour des raisons de propreté du code et de facilité de maintenance, mais je tiens à préciser que cela n'a rien à voir avec la vitesse .


0

Vous testez, en utilisant include, l'alternative d'oli et __autoload (); et testez-le avec quelque chose comme APC installé.

Je doute que l'utilisation de la constante accélérera les choses.


0

Oui, c'est un peu plus cher que le simple besoin (). Je pense que si vous pouvez garder votre code suffisamment organisé pour ne pas dupliquer les inclusions, n'utilisez pas les fonctions * _once (), car cela vous fera gagner quelques cycles.

Mais l'utilisation des fonctions _once () ne va pas tuer votre application. En gros, ne l'utilisez pas comme excuse pour ne pas avoir à organiser vos inclusions . Dans certains cas, son utilisation est toujours inévitable, et ce n'est pas un gros problème.


-2

Je pense que dans la documentation PEAR, il y a une recommandation pour require, require_once, include et include_once. Je suis cette directive. Votre candidature serait plus claire.


Certaines références seraient en règle.
Peter Mortensen

-3

Cela n'a rien à voir avec la vitesse. Il s'agit d'échouer gracieusement.

Si require_once () échoue, votre script est terminé. Rien d'autre n'est traité. Si vous utilisez include_once (), le reste de votre script essaiera de continuer à être rendu, de sorte que vos utilisateurs ne seraient potentiellement pas plus avisés de quelque chose qui a échoué dans votre script.


1
Pas nécessairement. Vous pouvez en fait accrocher un gestionnaire d'erreur ou un gestionnaire d'arrêt pour donner à l'utilisateur une belle page d'erreur (bien que les gens le fassent rarement). En tant que développeur, je préférerais de loin les erreurs immédiates.
Edward Z. Yang

1
Ou, selon le cas, ne pas échouer gracieusement - si un fichier vital n'est pas requis () correctement, c'est une bonne idée d'abandonner et de s'arrêter. Mais c'est require vs include, alors que je pense que la question est plus centrée sur require vs require_once.
HoboBen

-4

Mon opinion personnelle est que l'utilisation de require_once (ou include_once) est une mauvaise pratique car require_once vérifie pour vous si vous avez déjà inclus ce fichier et supprime les erreurs des fichiers double inclus entraînant des erreurs fatales (comme la déclaration en double de fonctions / classes / etc.) .

Vous devez savoir si vous devez inclure un fichier.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.