Ci sono molte ragioni per cui si potrebbe riscontrare questo errore e quindi una buona lista di controllo su cosa controllare prima aiuta considerevolmente.
Consideriamo che stiamo risolvendo i problemi con la seguente riga:
require "/path/to/file"
lista di controllo
1. Controllare il percorso del file per errori di battitura
- controllare manualmente (controllando visivamente il percorso)
o sposta qualunque cosa sia chiamata da require*
o include*
alla sua stessa variabile, fai eco, copiala e prova ad accedervi da un terminale:
$path = "/path/to/file";
echo "Path : $path";
require "$path";
Quindi, in un terminale:
cat <file path pasted>
2. Verificare che il percorso del file sia corretto per quanto riguarda le considerazioni relative al percorso relativo o assoluto
- se inizia con una barra "/", non si riferisce alla radice della cartella del tuo sito Web (la radice del documento), ma alla radice del tuo server.
- ad esempio, potrebbe essere la directory del tuo sito web
/users/tony/htdocs
- se non viene avviato da una barra, si basa sul percorso di inclusione (vedere di seguito) o il percorso è relativo. Se è relativo, PHP calcolerà relativamente al percorso della directory di lavoro corrente .
- quindi, non relativo al percorso della radice del tuo sito web, o al file in cui stai digitando
- per questo motivo, utilizzare sempre percorsi di file assoluti
Migliori pratiche :
Al fine di rendere robusto lo script nel caso in cui si spostino cose, pur generando un percorso assoluto in fase di esecuzione, sono disponibili 2 opzioni:
- usare
require __DIR__ . "/relative/path/from/current/file"
. La __DIR__
costante magica restituisce la directory del file corrente.
definisci SITE_ROOT
tu stesso una costante:
- alla radice della directory del tuo sito web, crea un file, ad es
config.php
in config.php
, scrivi
define('SITE_ROOT', __DIR__);
in ogni file in cui si desidera fare riferimento alla cartella principale del sito, includere config.php
e quindi utilizzare la SITE_ROOT
costante dove preferisci:
require_once __DIR__."/../config.php";
...
require_once SITE_ROOT."/other/file.php";
Queste 2 pratiche rendono anche la tua applicazione più portatile perché non si basa su impostazioni ini come il percorso include.
3. Controlla il tuo percorso di inclusione
Un altro modo per includere i file, né relativamente né semplicemente, è fare affidamento sul percorso include . Questo è spesso il caso di librerie o framework come il framework Zend.
Tale inclusione sarà simile a questa:
include "Zend/Mail/Protocol/Imap.php"
In tal caso, dovrai assicurarti che la cartella in cui si trova "Zend" sia parte del percorso di inclusione.
Puoi controllare il percorso di inclusione con:
echo get_include_path();
Puoi aggiungere una cartella con:
set_include_path(get_include_path().":"."/path/to/new/folder");
4. Verifica che il tuo server abbia accesso a quel file
Potrebbe essere che tutti insieme, l'utente che esegue il processo del server (Apache o PHP) semplicemente non abbia il permesso di leggere o scrivere su quel file.
Per verificare sotto quale utente è in esecuzione il server è possibile utilizzare posix_getpwuid :
$user = posix_getpwuid(posix_geteuid());
var_dump($user);
Per scoprire le autorizzazioni sul file, digitare il seguente comando nel terminale:
ls -l <path/to/file>
e guarda l' autorizzazione notazione simbolica
5. Controlla le impostazioni di PHP
Se nessuna delle precedenti funzioni ha funzionato, probabilmente il problema è che alcune impostazioni di PHP gli vietano di accedere a quel file.
Tre impostazioni potrebbero essere rilevanti:
- open_basedir
- Se impostato, PHP non sarà in grado di accedere a nessun file al di fuori della directory specificata (nemmeno attraverso un collegamento simbolico).
- Tuttavia, il comportamento predefinito prevede che non venga impostato, nel qual caso non vi sono restrizioni
- Questo può essere verificato chiamando
phpinfo()
o usandoini_get("open_basedir")
- È possibile modificare l'impostazione modificando il file php.ini o il file httpd.conf
- modalità sicura
- se questa opzione è attivata, potrebbero essere applicate restrizioni. Tuttavia, questo è stato rimosso in PHP 5.4. Se sei ancora su una versione che supporta l'aggiornamento in modalità provvisoria a una versione PHP ancora supportata .
- allow_url_fopen e allow_url_include
- questo vale solo per l'inclusione o l'apertura di file attraverso un processo di rete come http: // non quando si tenta di includere file nel file system locale
- questo può essere verificato con
ini_get("allow_url_include")
e impostato conini_set("allow_url_include", "1")
Custodie angolari
Se nessuna delle opzioni precedenti è abilitata a diagnosticare il problema, ecco alcune situazioni speciali che potrebbero verificarsi:
1. L'inclusione della libreria basandosi sul percorso include
Può succedere che tu includa una libreria, ad esempio il framework Zend, usando un percorso relativo o assoluto. Per esempio :
require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"
Ma poi ricevi ancora lo stesso tipo di errore.
Ciò può accadere perché il file che hai (correttamente) incluso, ha esso stesso un'istruzione include per un altro file e la seconda istruzione include presuppone che tu abbia aggiunto il percorso di quella libreria al percorso include.
Ad esempio, il file framework Zend menzionato in precedenza potrebbe includere quanto segue:
include "Zend/Mail/Protocol/Exception.php"
che non è né un'inclusione per percorso relativo, né per percorso assoluto. Si presuppone che la directory del framework Zend sia stata aggiunta al percorso include.
In tal caso, l'unica soluzione pratica è aggiungere la directory al percorso di inclusione.
2. SELinux
Se stai eseguendo Security-Enhanced Linux, potrebbe essere la ragione del problema, negando l'accesso al file dal server.
Per verificare se SELinux è abilitato sul tuo sistema, esegui il sestatus
comando in un terminale. Se il comando non esiste, SELinux non è sul tuo sistema. Se esiste, allora dovrebbe dirti se è applicato o meno.
Per verificare se i criteri SELinux sono il motivo del problema, puoi provare a disattivarlo temporaneamente. Tuttavia, ATTENZIONE, poiché ciò disabiliterà completamente la protezione. Non farlo sul server di produzione.
setenforce 0
Se il problema con SELinux non è più disattivato, questa è la causa principale.
Per risolverlo , dovrai configurare SELinux di conseguenza.
Saranno necessari i seguenti tipi di contesto:
httpd_sys_content_t
per i file che vuoi che il tuo server sia in grado di leggere
httpd_sys_rw_content_t
per i file su cui si desidera accedere in lettura e scrittura
httpd_log_t
per i file di registro
httpd_cache_t
per la directory della cache
Ad esempio, per assegnare il httpd_sys_content_t
tipo di contesto alla directory principale del sito Web, eseguire:
semanage fcontext -a -t httpd_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root
Se il tuo file si trova in una home directory, dovrai anche attivare il valore httpd_enable_homedirs
booleano:
setsebool -P httpd_enable_homedirs 1
In ogni caso, potrebbero esserci vari motivi per cui SELinux negherebbe l'accesso a un file, a seconda delle vostre politiche. Quindi dovrai indagare su questo. Ecco un tutorial specifico sulla configurazione di SELinux per un server web.
3. Symfony
Se stai usando Symfony e stai riscontrando questo errore durante il caricamento su un server, è possibile che la cache dell'app non sia stata ripristinata, sia perché app/cache
è stata caricata, sia che la cache non è stata cancellata.
Puoi testarlo e correggerlo eseguendo il seguente comando console:
cache:clear
4. Caratteri non ACSII all'interno del file zip
Apparentemente, questo errore può verificarsi anche quando si chiama zip->close()
quando alcuni file all'interno dello zip hanno caratteri non ASCII nel loro nome file, come "é".
Una potenziale soluzione è racchiudere il nome del file utf8_decode()
prima di creare il file di destinazione.
Ringraziamo Fran Cano per aver identificato e suggerito una soluzione a questo problema