2013-08-20 12 views
6

Mój skrypt Phar tworzy nowy plik z fwrite, który działa dobrze, tworzy nowy plik poza phar, w tym samym katalogu, co plik phar.PHP Phar - file_exists() wydanie

Ale wtedy, gdy używam, jeśli (file_exists ("file.php")) nie pobiera go.

Ale wtedy dołącz i wymagaj, aby go odebrać.

Ktoś wie o tym problemie? Testowanie i wyszukiwanie przez chwilę nie może znaleźć rozwiązania.

+0

Jaką wersję PHP? Owijarki adresów URL mogą tylko na wersjach => PHP 5.0.0 –

+0

Czy wypróbowałeś następujące zalecenie z dokumentacji dla ['file_exists()'] (http://php.net/file_exists): "Uwaga: Wyniki tej funkcji są buforowane. Zobacz clearstatcache() po więcej szczegółów. "? –

+0

Tak, próbowałem clearstatcache() - ale pamięć podręczna zapisałaby go jako "istnieje", a moim problemem jest to, że go nie znajduje - więc to zdecydowanie nie jest winowajcą. – Lan

Odpowiedz

4

Praca ze ścieżkami plików i Phar archiwum

Praca ze ścieżkami plików i archiwów Phar w PHP może być trudne. Kod PHP wewnątrz pliku Phar traktuje względne ścieżki jako względne do archiwum Phara, , a nie względem bieżącego katalogu roboczego. Oto krótki przykład:

Powiedzmy, że masz następujące pliki:

phar/index.php 
test.php 
my.phar 

Plik index.php znajduje się wewnątrz katalogu Phar. Jest to plik bootstrap dla archiwum Phar:

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

pliku uruchamiającego jest wykonywany, gdy plik Phar wliczone jest ze skryptu PHP. Nasz plik bootstrap po prostu spowoduje, że zostanie zadeklarowana funkcja "does_it_exist".

Spróbujmy uruchomiony inny kod wewnątrz test.php i zobaczyć, jakie wyniki są dla każdego biegu:

//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" 

Spójrz na biegu 4. Kod ten zawiera plik Phar i przekazuje funkcję ścieżki względnej. W stosunku do bieżącego katalogu roboczego index.php nie istnieje. Ale w stosunku do zawartości archiwum phar istnieje, dlatego wypisuje "true"!

+0

Wiem, wiem. to nie jest pytanie. mój pakiet phar tworzy nowy plik POZA scenariuszem phar używając fwrite. który działa idealnie, tworzony jest nowy plik. i ten nowy może być później odczytany przez włączanie lub wymaganie, ale nie może być "widziany" przez file_exists - który jest moim problemem - myślę, że może to być błąd w phar – Lan

+0

@LAN odpowiedziałeś, że zapytałeś – Vineet1982

+0

dzięki, ale jeśli dołączono ('zaloguj się .php ') lub wymagają (' login.php ') zarówno odszukują, jak i odczytają plik, niż na pewno, jeśli (file_exists (' login.php ')) zwrócą prawdę - na pewno fakt, że jego odczyt przez include/require pokazuje, że ścieżka/lokalizacja pliku jest poprawna, i że czy to nie problem? – Lan

1

Nie wiem, co jest przyczyną file_exists() na niepowodzenie, ale można spróbować czegoś jak ten

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

ahh dobry pomysł. dzięki. czy muszę go później zamknąć, aby zachować więcej legit? – Lan

+1

Tak, oczywiście! Możesz go potem zamknąć, jeśli funkcja fopen się powiedzie. Otwórz plik, jeśli zakończy się pomyślnie, zamknij plik i zwróć true, w przeciwnym razie zwróci false. – Konsole

2

file_exists w php ma kilka problemów w konkretnych przypadkach.

Zamiast tego polecam użyć stat(), co jest zwykle preferowanym sposobem uzyskania tych informacji, nie tylko w php. Nie zapomnij wyczyścić pamięci podręcznej, dzwoniąc pod numer clearstatcache().

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

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

Uwaga: Staram się unikać operatora eliminują @ tyle, ile mogę, ale widzę, tym konkretnym przypadku jako neccessary go używać :)

7

Na odgałęzienie w Phar, można użyć __DIR__ magii ciągłe, aby uzyskać folder plików PHAR.

Mając to na uwadze, można po prostu użyć

is_file(__DIR__ . DIRECTORY_SEPARATOR . $path); 

Aby sprawdzić istnienie danego pliku, poza Phar.

Można to zrobić TYLKO z kodu pośredniczącego i TYLKO w przypadku niestandardowego kodu pośredniczącego, w przeciwieństwie do kodu wygenerowanego przez Phar :: setDefaultStub(). Jeśli musisz sprawdzić pliki w dalszej części, będziesz musiał jakoś udostępnić wartość tej stałej, np. Zmienną globalną, niestandardową stałą niemagiczną lub statyczną właściwość lub coś, z czym inne pliki skonsultują się.

EDYCJA: W rzeczywistości można również użyć dirname(Phar::running(false)), aby uzyskać folder PHAR z dowolnego miejsca w PHAR. Ta funkcja zwraca pusty ciąg znaków, jeśli nie znajdujesz się w obrębie PHAR, więc jeśli aplikacja jest wykonywana jako PHAR lub bezpośrednio, powinna działać poprawnie, np.

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

Mogę odtworzyć to zachowanie, dzwoniąc pod numer Phar::interceptFileFuncs(). Wydaje się, że wywołania fopen w trybie zapisu nie są przechwytywane, podczas gdy funkcje związane ze statystyką są.

Od absolutne nazwy plików są traktowane jako związane z plików nawet w archiwach Phar że funkcje plików przechwytujący:

[...] Bezwzględne ścieżki są uważane za próby wczytania zewnętrznych plików z systemu plików.

... jeden ze sposobów radzenia sobie z tym problemem jest wykorzystanie realpath():

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

spotykam ten sam problem dzisiaj. Po kilku godzinach kopania ... znalazłem odpowiedź.

Czy możesz najpierw wypróbować poniższy skrypt?

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

Jeśli plik istnieje, to problem jest

jeśli używasz tylko nazwę pliku bez ścieżki dostępu, plik php uczta jest związane Phar odgałęzienie. na przykład:

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

Tak, trzeba użyć ścieżki bezwzględnej manipulować pliku, na przykład:

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

nadzieję, że to pomaga.

Mark