W skryptach PHP, czy powołanie include()
, require()
, fopen()
lub ich pochodne, takie jak include_once
, require_once
lub nawet move_uploaded_file()
jeden często prowadzi do wystąpienia błędu lub ostrzeżenia:
Nie udało się otworzyć strumienia: brak takiego pliku lub katalogu.
Jaki jest dobry proces szybkiego znajdowania pierwotnej przyczyny problemu?
php
require
fopen
include-path
Vic Seedoubleyew
źródło
źródło
Odpowiedzi:
Istnieje wiele powodów, dla których ktoś może napotkać ten błąd, a zatem dobra lista kontrolna tego, co należy sprawdzić najpierw, znacznie pomaga.
Rozważmy, że rozwiązujemy problem z następującym wierszem:
Lista kontrolna
1. Sprawdź ścieżkę do pliku pod kątem literówek
lub przenieś cokolwiek jest wywoływane przez
require*
lubinclude*
do jego własnej zmiennej, powtórz to, skopiuj i spróbuj uzyskać do niego dostęp z terminala:Następnie w terminalu:
2. Sprawdź, czy ścieżka do pliku jest poprawna pod względem względów względnych i bezwzględnych
/users/tony/htdocs
Najlepsze praktyki :
Aby Twój skrypt był niezawodny na wypadek przenoszenia elementów, jednocześnie generując bezwzględną ścieżkę w czasie wykonywania, masz 2 opcje:
require __DIR__ . "/relative/path/from/current/file"
.__DIR__
Stała magia zwraca katalogu bieżącego pliku.sam zdefiniuj
SITE_ROOT
stałą:config.php
w
config.php
, napiszw każdym pliku, do którego chcesz odwołać się do folderu głównego serwisu, dołącz
config.php
, a następnie użyjSITE_ROOT
stałej, gdziekolwiek chcesz:Te dwie praktyki sprawiają, że aplikacja jest bardziej przenośna, ponieważ nie opiera się na ustawieniach ini, takich jak ścieżka dołączania.
3. Sprawdź ścieżkę dołączania
Innym sposobem dołączania plików, ani względnym, ani czysto absolutnym, jest poleganie na ścieżce dołączania . Dzieje się tak często w przypadku bibliotek lub frameworków, takich jak framework Zend.
Takie włączenie będzie wyglądać następująco:
W takim przypadku będziesz chciał się upewnić, że folder, w którym znajduje się „Zend”, jest częścią ścieżki dołączania.
Możesz sprawdzić ścieżkę dołączania za pomocą:
Możesz dodać do niego folder za pomocą:
4. Sprawdź, czy serwer ma dostęp do tego pliku
Może się tak zdarzyć, że użytkownik uruchamiający proces serwera (Apache lub PHP) po prostu nie ma uprawnień do odczytu lub zapisu w tym pliku.
Aby sprawdzić, pod jakim użytkownikiem działa serwer, możesz użyć posix_getpwuid :
Aby sprawdzić uprawnienia do pliku, wpisz następujące polecenie w terminalu:
i spójrz na symboliczną notację pozwolenia
5. Sprawdź ustawienia PHP
Jeśli żadne z powyższych nie zadziałało, problem prawdopodobnie polega na tym, że niektóre ustawienia PHP zabraniają mu dostępu do tego pliku.
Istotne mogą być trzy ustawienia:
phpinfo()
lub używającini_get("open_basedir")
ini_get("allow_url_include")
i ustawić za pomocąini_set("allow_url_include", "1")
Skrzynie narożne
Jeśli żadne z powyższych nie umożliwiło zdiagnozowania problemu, oto kilka specjalnych sytuacji, które mogą się zdarzyć:
1. Włączenie biblioteki korzystającej ze ścieżki dołączania
Może się zdarzyć, że włączysz bibliotekę, na przykład framework Zend, używając ścieżki względnej lub bezwzględnej. Na przykład :
Ale nadal pojawia się ten sam rodzaj błędu.
Może się tak zdarzyć, ponieważ plik, który został (pomyślnie) dołączony, sam zawiera instrukcję include dla innego pliku, a ta druga instrukcja include zakłada, że dodano ścieżkę tej biblioteki do ścieżki dołączania.
Na przykład wspomniany wcześniej plik frameworka Zend może zawierać następujące elementy:
co nie jest ani włączeniem przez ścieżkę względną, ani przez ścieżkę absolutną. Zakłada się, że katalog frameworka Zend został dodany do ścieżki włączania.
W takim przypadku jedynym praktycznym rozwiązaniem jest dodanie katalogu do ścieżki dołączania.
2. SELinux
Jeśli używasz systemu Linux z rozszerzonymi zabezpieczeniami, przyczyną problemu może być odmowa dostępu do pliku z serwera.
Aby sprawdzić, czy SELinux jest włączony w twoim systemie, uruchom
sestatus
polecenie w terminalu. Jeśli polecenie nie istnieje, oznacza to, że SELinuksa nie ma w twoim systemie. Jeśli istnieje, powinien poinformować Cię, czy jest wymuszony, czy nie.Aby sprawdzić, czy przyczyną problemu są polityki SELinux , możesz spróbować tymczasowo je wyłączyć. Należy jednak uważać, ponieważ spowoduje to całkowite wyłączenie ochrony. Nie rób tego na serwerze produkcyjnym.
Jeśli nie masz już problemu z wyłączonym SELinuksem, to jest to główna przyczyna.
Aby go rozwiązać , będziesz musiał odpowiednio skonfigurować SELinux.
Niezbędne będą następujące typy kontekstów:
httpd_sys_content_t
dla plików, które serwer ma mieć możliwość odczytuhttpd_sys_rw_content_t
dla plików, dla których chcesz mieć dostęp do odczytu i zapisuhttpd_log_t
dla plików dziennikahttpd_cache_t
dla katalogu pamięci podręcznejNa przykład, aby przypisać
httpd_sys_content_t
typ kontekstu do katalogu głównego serwisu WWW, uruchom:Jeśli twój plik znajduje się w katalogu domowym, musisz również włączyć wartość
httpd_enable_homedirs
logiczną:W każdym razie może istnieć wiele powodów, dla których SELinux mógłby odmówić dostępu do pliku, w zależności od polityki użytkownika. Więc będziesz musiał się o to dowiedzieć. Oto samouczek dotyczący konfigurowania SELinux dla serwera WWW.
3. Symfony
Jeśli używasz Symfony i napotykasz ten błąd podczas przesyłania na serwer, może to być spowodowane tym, że pamięć podręczna aplikacji nie została zresetowana, ponieważ
app/cache
została załadowana lub pamięć podręczna nie została wyczyszczona.Możesz to przetestować i naprawić, uruchamiając następujące polecenie konsoli:
4. Znaki inne niż ACSII w pliku ZIP
Najwyraźniej ten błąd może wystąpić również podczas wywoływania,
zip->close()
gdy niektóre pliki w pliku zip mają w nazwie znaki inne niż ASCII, takie jak „é”.Potencjalnym rozwiązaniem jest zawinięcie nazwy pliku
utf8_decode()
przed utworzeniem pliku docelowego.Podziękowania dla Fran Cano za zidentyfikowanie i zasugerowanie rozwiązania tego problemu
źródło
selinux
może być dobrym pomysłem. będziesz potrzebować przynajmniejhttpd_sys_content_t
uprawnień (tylko do odczytu katalogów i plików używanych przez Apache) dla dołączonych plików.chcon
jest tymczasowy i nie przetrwarestorecon
ani ponownego uruchomienia. może być konieczne użyciesemanage
do zmiany kontekstu pliku. Oto dobry, prosty poradnik dla strony internetowejAby dodać do (naprawdę dobrej) istniejącej odpowiedzi
Współdzielone oprogramowanie hostingowe
open_basedir
to taki, który może cię zranić, ponieważ można go określić w konfiguracji serwera WWW. Chociaż można to łatwo naprawić, jeśli uruchomisz własny serwer dedykowany, istnieją pewne pakiety oprogramowania do hostingu współdzielonego (takie jak Plesk, cPanel itp.), Które skonfigurują dyrektywę konfiguracyjną dla każdej domeny. Ponieważ oprogramowanie tworzy plik konfiguracyjny (tj.httpd.conf
), Nie można bezpośrednio zmienić tego pliku, ponieważ oprogramowanie hostingowe po prostu nadpisze go po ponownym uruchomieniu.Plesk zapewnia miejsce do zastąpienia podanego
httpd.conf
wywołaniavhost.conf
. Tylko administrator serwera może zapisać ten plik. Konfiguracja Apache wygląda mniej więcej takPoproś administratora serwera o zapoznanie się z instrukcją obsługi hostingu i oprogramowania serwera WWW, z którego korzysta.
Uprawnienia do plików
Ważne jest, aby pamiętać, że wykonanie pliku za pośrednictwem serwera WWW bardzo różni się od wykonania zadania z wiersza poleceń lub cron. Największą różnicą jest to, że serwer WWW ma własnego użytkownika i uprawnienia. Ze względów bezpieczeństwa ten użytkownik jest dość ograniczony. Apache, na przykład, jest często
apache
,www-data
lubhttpd
(w zależności od serwera). Zadanie cron lub wykonanie CLI ma wszelkie uprawnienia, jakie ma uruchamiający je użytkownik (tj. Uruchomienie skryptu PHP jako root będzie wykonywane z uprawnieniami roota).Często ludzie rozwiązują problem z uprawnieniami, wykonując następujące czynności (przykład z Linuksem)
Nie jest to mądry pomysł, ponieważ plik lub katalog jest teraz dostępny dla wszystkich. Jeśli jesteś właścicielem serwera i jesteś jedynym użytkownikiem, nie jest to taka wielka sprawa, ale jeśli korzystasz ze współdzielonego środowiska hostingowego, właśnie dałeś wszystkim dostęp do serwera.
Musisz tylko określić użytkowników, którzy potrzebują dostępu, i dać dostęp tylko tym, którym są one potrzebne. Gdy już wiesz, którzy użytkownicy potrzebują dostępu, będziesz chciał się upewnić
Ten użytkownik jest właścicielem pliku i prawdopodobnie katalogu nadrzędnego (zwłaszcza katalogu nadrzędnego, jeśli chcesz zapisywać pliki). W większości współdzielonych środowisk hostingowych nie będzie to problemem, ponieważ użytkownik powinien być właścicielem wszystkich plików znajdujących się w katalogu głównym. Przykład Linuksa pokazano poniżej
Użytkownik i tylko ten użytkownik ma dostęp. W Linuksie dobrą praktyką byłoby
chmod 600
(tylko właściciel może czytać i pisać) lubchmod 644
(właściciel może pisać, ale każdy może czytać)Możesz przeczytać bardziej rozszerzone omówienie uprawnień i użytkowników Linuksa / Uniksa tutaj
źródło
Mój kod działał dobrze na wszystkich maszynach, ale tylko na tym zaczął powodować problem (który, jak sądzę, działał). Użyłem ścieżki echo „document_root” do debugowania, a także przyjrzałem się uważnie błędowi, znalazłem to
Możesz łatwo zobaczyć, gdzie są problemy. Problemy występują // przed funkcjami
Po prostu usuń ładunek / z dołączenia i powinno działać dobrze. Co ciekawe, zachowanie to jest różne w różnych wersjach. Uruchomiłem ten sam kod na laptopie, Macbooku Pro i tym komputerze PC, wszystko działało dobrze do tej pory. Mam nadzieję, że to komuś pomoże.
źródło
Dodaj skrypt z parametrami zapytania
To był mój przypadek. W rzeczywistości prowadzi do pytania nr 4485874 , ale wkrótce to wyjaśnię.
Kiedy próbujesz wymagać
path/to/script.php?parameter=value
, PHP szuka pliku o nazwiescript.php?parameter=value
, ponieważ UNIX pozwala na takie ścieżki.Jeśli naprawdę potrzebujesz, aby przekazać niektóre dane zawarte skryptu, po prostu zadeklarować ją jako
$variable=...
lub$GLOBALS[]=...
czy inny sposób chcesz.źródło
Akcje Samby
Jeśli masz serwer testowy Linux i pracujesz z klienta Windows, udział Samba koliduje z poleceniem chmod . Tak więc, nawet jeśli używasz:
po stronie Linuksa jest w pełni możliwe, że Unix Group \ www-data nadal nie ma prawa do zapisu. Jedno działające rozwiązanie, jeśli Twój udział jest skonfigurowany tak, że administratorzy systemu Windows są zmapowani do katalogu głównego: W systemie Windows otwórz uprawnienia, wyłącz dziedziczenie dla swojego folderu z kopiowaniem, a następnie udziel pełnego dostępu do danych www.
źródło
Inna możliwa przyczyna: zmiana nazwy i / lub przenoszenie plików w edytorze tekstu. Wykonałem wszystkie powyższe kroki bez powodzenia, dopóki nie usunąłem pliku, który ciągle zgłaszał ten błąd i utworzyłem nowy, który naprawił problem.
źródło