Сегодня я зашел на свой сервер разработки и обнаружил, что PHP не смог включить некоторые файлы с этим сообщением E_WARNING:
Предупреждение: include_once (../ file2.php) [function.include-once]: не удалось открыть поток: нет такого файла или каталога в /var/www/web/some_directory_1/file1.php в любой строке
Я немного покопался с нашим системным администратором, и мы обнаружили, что PHP терпит неудачу только тогда, когда он пытается включить пути к файлам с помощью '../' или './' в пути.
Предположим, наша файловая структура выглядит так:
/ var / www / web /
- index.php
- file2.php
- some_directory_1 /
---- file1.php
---- file3.php
Если file1.php хочет включить file2.php, это сработает:
include_once('/var/www/web/file2.php');
Но этого не будет:
include_once('../file2.php');
Подожди секунду ... Я знаю, о чем ты думаешь! "О, их include_path - это просто FUBAR". Не совсем так.
Если вы сделаете это в index.php, это будет работать:
include_once('some_directory_1/file1.php');
И если вы сделаете это в file1.php, это тоже сработает:
include_once('file3.php');
Наш include_path установлен на .:/usr/lib/php
. За последние 24 часа ничего в серверной среде не изменилось (никаких обновлений, никакого нового программного обеспечения, никаких изменений включений, никаких изменений в конфигурациях Apache или PHP), я и системный администратор были единственными людьми, которые обращались к серверу в последние 24 часа, а вчера все работало нормально. Мы исчерпали список возможных причин. Есть какие-нибудь подсказки, что могло вызвать это?
Редактировать: Забыл предупреждающее сообщение PHP.
Причина, по которой у вас возникают проблемы, заключается в том, что относительный путь в include / require всегда относительный к исходному сценарию, а использование относительного пути заставляет php игнорировать значение include_path. Итак, в вашем примере include_once('../file2.php');
ищет файл в родительском элементе index.php, если index.php является исходным скриптом.
Не уверен, почему это внезапно изменилось. Но решение состоит в том, чтобы не использовать относительные пути - либо используйте include_path, либо используйте __DIR__
/dirname()
как предложено в комментариях.