Perché Require_once è così male da usare?


143

Tutto ciò che leggo sulle migliori pratiche di codifica PHP continua a dire di non usare a require_oncecausa della velocità.

Perchè è questo?

Qual è il modo migliore / migliore per fare la stessa cosa require_once? Se è importante, sto usando PHP 5.


9
Questa domanda è piuttosto vecchia ora e le risposte sono dubbiosamente più pertinenti. Sarebbe bello vedere una serie aggiornata di risposte dai partecipanti :)
Purefan,

Risposte:


108

require_onceed include_onceentrambi richiedono che il sistema mantenga un registro di ciò che è già stato incluso / richiesto. Ogni *_oncemezzi di chiamata di controllo che di registro. Quindi c'è sicuramente un po 'di lavoro extra svolto lì, ma abbastanza a discapito della velocità di tutto l'app?

... Ne dubito davvero ... A meno che tu non abbia hardware molto vecchio o lo faccia molto .

Se si sta facendo migliaia di *_once, si potrebbe fare il lavoro da soli in modo più leggero. Per le app semplici, assicurarti di averlo incluso solo una volta dovrebbe essere sufficiente, ma se continui a ridefinire gli errori, potresti fare qualcosa del genere:

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

Seguirò personalmente le *_onceaffermazioni ma sul benchmark stupido da un milione di passaggi, puoi vedere una differenza tra i due:

                php                  hhvm
if defined      0.18587779998779     0.046600103378296
require_once    1.2219581604004      3.2908599376678

10-100 × più lento con require_onceed è curioso che require_oncesia apparentemente più lento hhvm. Ancora una volta, questo è rilevante solo per il tuo codice se lo stai eseguendo *_oncemigliaia di volte.


<?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
Dubito che il tuo metodo definito () sia più veloce della tabella di ricerca integrata, ma sono d'accordo con il tuo punto generale - sicuramente un non-problema ?!
Bobby Jack,

1
Sono abbastanza sicuro che tu abbia ragione Bobby, ma non sto sostenendo le definizioni su _once. È solo un'opzione. Il tempo necessario per interpretare il codice potrebbe anche renderlo leggermente più lento ma, detto ciò, non so quanto sia accurato il metodo interno. Potrebbe fare un lavoro extra per garantire che non vi siano duplicati.
Oli,

8
L'altro
aspetto

3
Ho appena fatto un test molto semplice dei due metodi: ho fatto 1.000.000 di iterazioni incluso un file che ha semplicemente definito un "testinclude" costante su true. Nel primo test, ho usato Require_once, il secondo ho usato if (! Definito ('testinclude')) e i risultati erano interessanti: Requisito: 0.81639003753662 Non definito: 0.17906713485718 Definito è 0.63732290267944 microsecondi più veloce.
Travis Weston,

Il caso con define sarà più veloce poiché non stai eseguendo alcun tipo di controllo extra come l'utilizzo di realpath. Non sta confrontando due cose che sono veramente le stesse.
jgmjgm,

150

Questa discussione mi fa rabbrividire, perché c'è già stata una "soluzione pubblicata", ed è, a tutti gli effetti, sbagliata. Enumeriamo:

  1. Le definizioni sono davvero costose in PHP. Puoi cercarlo o testarlo tu stesso, ma l'unico modo efficace per definire una costante globale in PHP è tramite un'estensione. (Le costanti di classe sono in realtà prestazioni abbastanza decenti per quanto riguarda, ma questo è un punto controverso, a causa di 2)

  2. Se stai usando in modo require_once()appropriato, cioè per l'inclusione delle classi, non hai nemmeno bisogno di una definizione; controlla seclass_exists('Classname') . Se il file che stai includendo contiene codice, cioè lo stai usando in modo procedurale, non c'è assolutamente alcun motivo che require_once()dovrebbe essere necessario per te; ogni volta che includi il file presumi di effettuare una chiamata di subroutine.

Quindi per un po ', molte persone hanno usato il class_exists() metodo per le loro inclusioni. Non mi piace perché è fugace, ma avevano buone ragioni per:require_once() era piuttosto inefficiente prima di alcune delle versioni più recenti di PHP. Ma questo è stato risolto, ed è mia opinione che il bytecode extra che dovresti compilare per il condizionale, e la chiamata al metodo extra, supererebbe di gran lunga qualsiasi controllo di hashtable interno.

Ora, un'ammissione: questa roba è difficile da testare, perché rappresenta così poco del tempo di esecuzione.

Ecco la domanda a cui dovresti pensare: include, come regola generale, sono costosi in PHP, perché ogni volta che l'interprete lo colpisce deve tornare alla modalità di analisi, generare i codici operativi e quindi tornare indietro. Se hai un 100+ include, questo avrà sicuramente un impatto sulle prestazioni. Il motivo per cui l'utilizzo o meno di require_once è una domanda così importante è perché rende la vita difficile per le cache degli opcode. Una spiegazione per questo può essere trovata qui, ma ciò che si riduce è che:

  • Se durante il tempo di analisi, sai esattamente quali file includere saranno necessari per l'intera durata della richiesta, require()quelli all'inizio e la cache opcode gestiranno tutto il resto per te.

  • Se non si esegue una cache del codice operativo, ci si trova in una situazione difficile. Incorporare tutte le tue inclusioni in un unico file (non farlo durante lo sviluppo, solo in produzione) può sicuramente aiutare a analizzare il tempo, ma è una seccatura da fare e, inoltre, devi sapere esattamente cosa includerai durante richiesta.

  • Il caricamento automatico è molto conveniente, ma lento, per il motivo che la logica di caricamento automatico deve essere eseguita ogni volta che viene eseguita un'inclusione. In pratica, ho scoperto che il caricamento automatico di più file specializzati per una richiesta non causa troppi problemi, ma non dovresti caricare automaticamente tutti i file necessari.

  • Se hai forse 10 inclusioni (questo è molto indietro nel calcolo della busta), non vale la pena fare tutto ciò che si masturba: basta ottimizzare le query del database o qualcosa del genere.


14
Questo ha 4 anni e per la maggior parte non si applica più define(), require_once()e defined()tutti impiegano circa 1-2 microsecondi ciascuno sulla mia macchina.
Daniel Beardsley,

72
Ma sono 2 microsecondi prima che l'utente abbia la pagina. Oltre un anno di visualizzazioni di pagina, ciò potrebbe salvare l'utente per 3 secondi interi! Potevano guardare un decimo di uno spot in quel momento! Pensa all'utente. Non sprecare microsecondi.
Andrew Ensley,

15
Solo così tutti sono a conoscenza del sarcasmo, un microsecondo è 1/1000000 di secondo.
Andy Chase,

1
@AndrewEnsley Ti sbagli semplicemente con tutto il tuo sarcasmo. Sei ignaro del fatto che PHP funziona anche con microprocessore, 1 microsecondo sul tuo PC è di diversi millisecondi su un microprocessore. E che dire di avere 20 file include, un progetto più grande? Questo è 20 volte diversi millisecondi di ritardo introdotti, quindi stiamo già raggiungendo un punto evidente per un essere umano. Se lo script viene chiamato frequentemente, si verificheranno problemi di prestazioni sul sistema. L'ottimizzazione non è uno scherzo e il mondo intero non gira intorno al tuo PC. Ci sono diecimila di CPU in uso.
Giovanni,

2
@John. Era uno scherzo di buon umore. Nessuna malizia intesa. Se vale la pena per te ottimizzare le tue inclusioni, vai avanti.
Andrew Ensley,

66

Mi sono incuriosito e ho controllato il link di Adam Backstrom a Tech Your Universe . Questo articolo descrive uno dei motivi che richiedono di essere utilizzato al posto di require_once. Tuttavia, le loro affermazioni non sono state all'altezza della mia analisi. Sarei interessato a vedere dove avrei potuto analizzare male la soluzione. Ho usato PHP 5.2.0 per i confronti.

Ho iniziato creando 100 file di intestazione che utilizzavano request_once per includere un altro file di intestazione. Ognuno di questi file sembrava simile a:

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

?>

Li ho creati usando un rapido hack di Bash:

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

In questo modo potrei facilmente scambiare tra l'utilizzo di request_once e Require quando si includono i file di intestazione. Ho quindi creato un app.php per caricare i cento file. Questo sembrava:

<?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);
?>

Ho contrastato le intestazioni Require_once con le intestazioni Require che utilizzavano un file di intestazione simile a:

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

Non ho trovato molta differenza quando eseguivo questo con request vs. Require_once. In effetti, i miei test iniziali sembravano implicare che un requisito era leggermente più veloce, ma non ci credo necessariamente. Ho ripetuto l'esperimento con 10000 file di input. Qui ho visto una differenza consistente. Ho eseguito il test più volte, i risultati sono vicini ma l'utilizzo di request_once utilizza in media 30,8 jiffie utente e 72,6 jiffie di sistema; l'utilizzo richiede utilizza in media 39,4 jiffies utente e 72,0 jiffies di sistema. Pertanto, sembra che il carico sia leggermente più basso usando request_once. Tuttavia, il tempo dell'orologio a muro è leggermente aumentato. Le 10.000 chiamate request_once utilizzano in media 10,15 secondi per il completamento e 10.000 chiamate in media richiedono 9,84 secondi.

Il prossimo passo è esaminare queste differenze. Ho usato strace per analizzare le chiamate di sistema che vengono effettuate.

Prima di aprire un file da request_once vengono effettuate le seguenti chiamate di sistema:

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

Questo contrasta con richiede:

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 implica che require_once dovrebbe effettuare più chiamate lstat64. Tuttavia, entrambi effettuano lo stesso numero di chiamate lstat64. Forse, la differenza è che non sto eseguendo APC per ottimizzare il codice sopra. Tuttavia, successivamente ho confrontato l'output di strace per le intere esecuzioni:

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

In effetti, ci sono circa altre due chiamate di sistema per file di intestazione quando si utilizza require_once. Una differenza è che require_once ha una chiamata aggiuntiva alla funzione time ():

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

L'altra chiamata di sistema è getcwd ():

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

Questo si chiama perché ho deciso il percorso relativo a cui si fa riferimento nei file hdrXXX. Se lo faccio come riferimento assoluto, l'unica differenza è la chiamata di tempo aggiuntivo (NULL) effettuata nel codice:

[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

Ciò sembra implicare che è possibile ridurre il numero di chiamate di sistema utilizzando percorsi assoluti anziché percorsi relativi. L'unica differenza al di fuori di questo è il tempo (NULL) chiamate che sembrano essere utilizzate per strumentare il codice per confrontare ciò che è più veloce.

Un'altra nota è che il pacchetto di ottimizzazione APC ha un'opzione chiamata "apc.include_once_override" che afferma che riduce il numero di chiamate di sistema effettuate dalle chiamate request_once e include_once (consultare la documentazione di PHP ).


6
E ogni "ottimizzazione" che devi eseguire 10.000 volte per vedere una tale minuscola differenza non è nemmeno degna di preoccuparsi. Usa un profiler e scopri dove si trovano i veri colli di bottiglia nella tua applicazione. Dubito che questa domanda sia il collo di bottiglia.
DGM

1
Ciò significa che non importa affatto. Usa ciò che funziona meglio per te logicamente.
Buttle Butkus,

wat are jiffies
OverCoder

21

Puoi darci qualche link a queste pratiche di codifica che dicono di evitarlo? Per quanto mi riguarda, è un totale problema . Non ho guardato il codice sorgente da solo, ma immagino che l'unica differenza tra includee include_oncesia che include_onceaggiunge quel nome file a un array e controlla ogni volta l'array. Sarebbe facile mantenere quell'array ordinato, quindi la ricerca su di esso dovrebbe essere O (log n), e anche un'applicazione medio-grande avrebbe solo un paio di dozzine di inclusioni.


uno è, chazzuka.com/blog/?p=163 davvero non "non", ma si sommano troppe cose "costose". e in realtà, tutti i file inclusi / richiesti vengono aggiunti a un array interno (esiste una funzione per restituirlo), immagino che gli _unce debbano eseguire il loop di quell'array e fare gli strcmp, il che si
sommerebbe

7

Un modo migliore per fare le cose è usare un approccio orientato agli oggetti e usare __autoload () .


3
ma il primo esempio nella pagina degli oggetti
caricati

Non lo compro. Ci sono MOLTE situazioni in cui OO non si adatta in modo appropriato come altri paradigmi, quindi non dovresti forzarlo solo per ottenere tutti i piccoli vantaggi che potrebbero esserci con __autoload ().
Bobby Jack,

1
penseresti che il caricamento automatico richiederebbe effettivamente più tempo di * _una volta (supponendo che tu stia solo richiedendo ciò di cui hai bisogno).
Nickf

No, almeno non sicuramente, il caricamento automatico deve ancora essere incluso in qualche modo ed è l'ultima risorsa per PHP prima che l'errore fallisca, quindi in realtà PHP esegue effettivamente controlli superflui in tutti i luoghi che si applicherebbero per includere / richiedere e DOPO CHE chiamerebbe autoload (se definito) ... PS: __autoload()è scoraggiato e potrebbe essere deprecato in futuro, dovresti usare spl_autoload_register(...)questi giorni ... PS2: non fraintendermi, a volte uso la funzionalità di caricamento automatico; )
jave.web,

6

Non sta usando la funzione che è male. È una comprensione errata di come e quando utilizzarlo, in una base di codice generale. Aggiungerò solo un po 'più di contesto a quell'idea forse fraintesa:

Le persone non dovrebbero pensare che require_once sia una funzione lenta. Devi includere il tuo codice in un modo o nell'altro. La velocità di require_once()vs. require()non è il problema. Riguarda le avvertenze che ostacolano le prestazioni che possono risultare nell'utilizzarlo alla cieca. Se usato ampiamente senza considerare il contesto, può portare a enormi sprechi di memoria o codice dispendioso.

Ciò che ho visto è davvero negativo, è quando enormi strutture monolitiche usano require_once()in tutti i modi sbagliati, specialmente in un ambiente orientato agli oggetti (OO) complesso.

Prendi l'esempio dell'uso require_once()nella parte superiore di ogni classe come visto in molte librerie:

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

Quindi la Userclasse è progettata per usare tutte e tre le altre classi. Giusto!

Ma ora cosa succede se un visitatore sta navigando nel sito e non ha nemmeno effettuato l'accesso e il framework viene caricato: require_once("includes/user.php");per ogni singola richiesta.

Comprende 1 + 3 classi non necessarie che non utilizzerà mai durante quella particolare richiesta. Ecco come i framework gonfiati finiscono per utilizzare 40 MB per richiesta anziché 5 MB o meno.


L'altro modo in cui può essere utilizzato in modo improprio è quando una classe viene riutilizzata da molti altri! Supponi di avere circa 50 classi che usano helperfunzioni. Per assicurarti che helperssiano disponibili per quelle classi quando vengono caricate, ottieni:

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

Non c'è nulla di sbagliato qui di per sé. Tuttavia, se una richiesta di pagina include 15 classi simili. Stai correndo require_once15 volte, o per una bella immagine:

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'uso di require_once () influenza tecnicamente le prestazioni per l'esecuzione di quella funzione 14 volte, oltre a dover analizzare quelle linee non necessarie. Con solo altre 10 classi molto usate con quel problema simile, potrebbe rappresentare oltre 100 righe di tale codice ripetitivo piuttosto inutile.

Con ciò, probabilmente vale la pena usarlo require("includes/helpers.php");al bootstrap dell'applicazione o del framework, invece. Ma poiché tutto è relativo, tutto dipende se il peso rispetto alla frequenza di utilizzo della helpersclasse vale la pena di salvare 15-100 linee di require_once(). Ma se la probabilità di non utilizzare il helpersfile su una determinata richiesta è nessuna, allora requiredovrebbe essere sicuramente nella tua classe principale. Avere require_oncein ogni classe separatamente diventa uno spreco di risorse.


La require_oncefunzione è utile quando necessario, ma non dovrebbe essere considerata una soluzione monolitica da utilizzare ovunque per caricare tutte le classi.


5

Il wiki PEAR2 (quando esisteva) elencava buone ragioni per abbandonare tutte le direttive di richiesta / inclusione a favore del caricamento automatico , almeno per il codice della libreria. Questi ti legano a rigide strutture di directory quando modelli di packaging alternativi come Phar sono all'orizzonte.

Aggiornamento: poiché la versione archiviata sul web della wiki è orribilmente brutta, ho copiato i motivi più convincenti di seguito:

  • include_path è necessario per utilizzare un pacchetto (PEAR). Ciò rende difficile raggruppare un pacchetto PEAR all'interno di un'altra applicazione con il proprio include_path, creare un singolo file contenente le classi necessarie, spostare un pacchetto PEAR in un archivio phar senza ampie modifiche al codice sorgente.
  • quando si richiede un livello_quisito di livello superiore con requisito_condizionale condizionale, ciò può comportare un codice che non può essere inserito nella cache di codici operativi come APC, che verrà raggruppato con PHP 6.
  • relative request_once richiede che include_path sia già impostato sul valore corretto, rendendo impossibile l'utilizzo di un pacchetto senza include_path corretto

5

Le *_once()funzioni indicano ogni directory principale per garantire che il file che stai includendo non sia uguale a quello già incluso. Questo è parte del motivo del rallentamento.

Consiglio di utilizzare uno strumento come Siege per il benchmarking. Puoi provare tutte le metodologie suggerite e confrontare i tempi di risposta.

Altro su require_once()è al Tech Your Universe .


Grazie per il puntatore all'articolo. Require_once () è una buona cintura di sicurezza su file con doppia inclusione e continueremo a usarlo, ma essere in grado di renderlo pulito è bello.
Andy Lester,

2

Anche se require_oncee include_once sono più lenti di requiree include(o di qualsiasi altra alternativa possa esistere), qui stiamo parlando del più piccolo livello di micro-ottimizzazione. Il tempo è molto meglio impiegato per ottimizzare quel ciclo o query di database scritti male che non preoccuparsi di qualcosa del genere require_once.

Ora, si potrebbe argomentare dicendo che require_onceconsente scarse pratiche di codifica perché non è necessario prestare attenzione a mantenere le proprie inclusioni pulite e organizzate, ma ciò non ha nulla a che fare con la funzione stessa e soprattutto non con la sua velocità.

Ovviamente, il caricamento automatico è migliore per motivi di pulizia del codice e facilità di manutenzione, ma voglio chiarire che questo non ha nulla a che fare con la velocità .


0

Test, usando include, l'alternativa di oli e __autoload (); e testalo con qualcosa come APC installato.

Dubito che l'uso di costante accelererà le cose.


0

Sì, è leggermente più costoso di quanto richieda (). Penso che il punto sia che puoi mantenere il tuo codice abbastanza organizzato da non duplicare le inclusioni, non usare le funzioni * _once (), in quanto ti salverà alcuni cicli.

Ma l'uso delle funzioni _once () non ucciderà l'applicazione. Fondamentalmente, non usarlo come scusa per non dover organizzare le tue inclusioni . In alcuni casi, l'utilizzo è ancora inevitabile e non è un grosso problema.


-2

Penso che nella documentazione PEAR vi sia una raccomandazione per request, request_once, include e include_once. Seguo questa linea guida. La tua domanda sarebbe più chiara.


Alcuni riferimenti sarebbero in ordine.
Peter Mortensen,

-3

Non ha nulla a che fare con la velocità. Si tratta di fallire con grazia.

Se request_once () non riesce, lo script è terminato. Nient'altro viene elaborato. Se usi include_once () il resto dello script proverà a continuare a renderizzare, quindi i tuoi utenti potrebbero essere potenzialmente meno saggi di qualcosa che non è riuscito nel tuo script.


1
Non necessariamente. Puoi effettivamente agganciare un gestore di errori o un gestore di arresto per dare all'utente una bella pagina di errore (anche se le persone raramente lo fanno). Come sviluppatore, preferirei che le cose si sbagliassero immediatamente.
Edward Z. Yang,

1
Oppure, a seconda dei casi, non fallire con garbo - se qualche file vitale non è richiesto () correttamente, è una buona idea solo arrendersi e fermarsi. Ma questo è necessario vs include, mentre penso che la domanda sia più focalizzata su require vs require_once.
HoboBen,

-4

La mia opinione personale è che l'uso di require_once (o include_once) è una cattiva pratica perché Require_once controlla per te se hai già incluso quel file e sopprime gli errori di file inclusi doppi con conseguenti errori fatali (come la duplice dichiarazione di funzioni / classi / ecc.) .

Dovresti sapere se devi includere un file.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.