2013-08-20 12 views
6

Il mio script Phar crea un nuovo file con fwrite, che funziona bene, crea il nuovo file al di fuori del phar, nella stessa directory del file phar.PHP Phar - file_exists() problema

Ma poi quando uso se (file_exists ('file.php')) non lo raccoglie.

Ma poi includere e richiedere lo raccogli.

Qualcuno sa di questo problema? Sono stati test e ricerche per un po 'che sembra impossibile trovare una soluzione.

+0

Quale versione di PHP? I wrapper di URL possono solo su verions => PHP 5.0.0 –

+0

Hai provato la seguente raccomandazione dalla documentazione di ['file_exists()'] (http://php.net/file_exists): "Nota: i risultati di questa funzione sono memorizzati nella cache. Vedi clearstatcache() per maggiori dettagli. "? –

+0

sì, ho provato il clearstatcache() - ma la cache lo memorizzerebbe come "esiste" e il mio problema è che non lo trova, quindi non è sicuramente il colpevole. – Lan

risposta

4

Lavorare con i percorsi dei file e gli archivi Phar

Lavorare con i percorsi dei file e gli archivi Phar in PHP può essere difficile. Il codice PHP all'interno di un file Phar considera i percorsi relativi come relativi all'archivio Phar, non relativo alla directory di lavoro corrente. Ecco un breve esempio:

Diciamo che sono i seguenti file:

phar/index.php 
test.php 
my.phar 

Il file index.php si trova all'interno della directory phar. E 'il file di bootstrap per l'archivio phar:

function does_it_exist($file){ 
    return file_exists($file) ? "true" : "false"; 
} 

viene eseguito il file di bootstrap quando il file è incluso phar da uno script PHP. Il nostro file bootstrap farà semplicemente dichiarare la funzione "does_it_exist".

Proviamo l'esecuzione di codice diverso all'interno di test.php e vedere quali sono i risultati per ogni corsa:

//Run 1: 
require_once 'phar/index.php'; //PHP file 
$file = __DIR__ . "/index.php"; //absolute path 
echo does_it_exist($file);  //prints "false" 

//Run 2: 
require_once 'phar/index.php'; //PHP file 
$file = "index.php";   //relative path 
echo does_it_exist($file);  //prints "false" 

//Run 3: 
require_once 'my.phar';   //phar file 
$file = __DIR__ . "/index.php"; //absolute path 
echo does_it_exist($file);  //prints "false" 

//Run 4: 
require_once 'my.phar';   //phar file 
$file = "index.php";   //relative path 
echo does_it_exist($file);  //prints "true" 

Guarda Run 4. Questo codice include il file phar e passa la funzione di un percorso relativo. Relativo alla directory di lavoro corrente, index.php non esiste. Ma rispetto al contenuto dell'archivio phar, esiste, ed è per questo che stampa "vero"!

+0

lo so, lo so. questa non è la domanda il mio pacchetto phar crea un nuovo file OUTSIDE dello script phar usando fwrite. che funziona perfettamente, viene creato un nuovo file. e questo nuovo può essere letto da includere o richiedere ma non può essere "visto" da file_exists - che è il mio problema - penso che potrebbe essere un bug in phar – Lan

+0

@Lan ha risposto che hai richiesto – Vineet1982

+0

grazie, ma se includi ('login .php ') o richiedere (' login.php ') entrambi trovano e leggono il file, che sicuramente se (file_exists (' login.php ')) restituirebbe true - sicuramente dal fatto che la sua lettura da include/require mostra che il percorso/posizione del file è corretto, e così non è il problema? – Lan

1

Non so che cosa sta causando file_exists() a fallire, ma si può provare qualcosa di simile

function fileExists($path){ 
    //try to open the file, if it can be read the file exist 
    return (@fopen($path,"r") == true); 
} 
+1

ahh buona idea. Grazie. ho bisogno di fclose in seguito per tenerlo più legittimo? – Lan

+1

Sì, naturalmente! Puoi chiuderlo in seguito se la funzione fopen ha successo. Apri il file, se riesce a chiudere il file e restituisce true, altrimenti restituisce false. – Konsole

2

file_exists in PHP ha diversi problemi, in casi particolari.

Ti consiglio di utilizzare invece stat(), che è comunemente preferibile per ottenere tali informazioni,
non solo in php. Inoltre, non dimenticare di svuotare la cache chiamando clearstatcache().

function FileExists($filename) 
{ 
    clearstatcache(false, $filename); 

    return false !== @stat($filename); 
} 

Nota: cerco di evitare l'operatore sopprimere @ per quanto posso, ma vedo questo caso particolare, come neccessary usarlo :)

7

Al stub del PHAR, è possibile utilizzare la magia __DIR__ costante per ottenere la cartella del file PHAR.

Con questo in mente, si può semplicemente utilizzare

is_file(__DIR__ . DIRECTORY_SEPARATOR . $path); 

Per verificare l'esistenza di un file al di fuori del PHAR.

È possibile farlo SOLAMENTE dallo stub e SOLO se si tratta di uno stub personalizzato, diversamente da uno generato da Phar :: setDefaultStub(). Se è necessario verificare la presenza di file più avanti sulla linea, sarà necessario rendere disponibile il valore di tale costante in qualche modo, come una variabile globale, una costante non magica personalizzata o una proprietà statica o qualcosa, che gli altri file quindi consultano.

MODIFICA: in realtà, è anche possibile utilizzare dirname(Phar::running(false)) per ottenere la cartella PHAR da qualsiasi posizione nel PHAR. Quella funzione restituisce una stringa vuota se non sei all'interno di un PHAR, quindi se la tua applicazione viene eseguita come PHAR o direttamente, dovrebbe funzionare bene, ad es.

$pharFile = Phar::running(false); 
is_file(('' === $pharFile ? '' : dirname($pharFile) . DIRECTORY_SEPARATOR) . $path) 
2

Posso riprodurre questo comportamento chiamando Phar::interceptFileFuncs(). Sembra che le chiamate fopen in modalità di scrittura non vengano intercettate, mentre le funzioni relative alle statistiche sono.

Poiché i nomi di file assoluti sono trattati come relativi al filesystem, anche in archivi Phar che le funzioni di file di intercettazione:

[...] I percorsi assoluti si presume siano i tentativi di caricare file esterni dal filesystem.

... un modo per affrontare il problema è quello di utilizzare realpath():

if (file_exists(realpath($filename)) { /* file exists on filesystem */ } 
4

mi capita di incontrare lo stesso problema di oggi. Dopo diverse ore di scavo ... ho trovato la risposta.

Puoi provare prima il seguente script?

if(file_exists(realpath('file.php'))); 

Se il file esiste, allora il problema è

se si utilizza solo il nome del file senza informazioni sul percorso, file php trattamento è legato alla phar stub. per esempio:

phar:///a/b/c/file.php

Quindi, è necessario utilizzare il percorso assoluto per manipolare il file, ad esempio:

/home/www/d/e/f/file.php

Spero che questo aiuto.

Mark