Проверьте, существует ли включение (или требование)
Как вы проверяете, существует ли include/require_once, прежде чем вызывать его, я попытался поместить его в блок ошибок, но PHP это не понравилось.
Я думаю, что file_exists()
будет работать с некоторыми усилиями, однако для этого потребуется весь путь к файлу, и относительное включение не может быть легко передано в него.
Есть ли другие способы?
6 answers
Я считаю, что file_exists
работает с относительными путями, хотя вы также можете попробовать что-то в этом роде...
if(!@include("script.php")) throw new Exception("Failed to include 'script.php'");
... излишне говорить, что вы можете заменить исключение любым методом обработки ошибок по вашему выбору. Идея здесь заключается в том, что оператор if
- проверяет, может ли файл быть включен, и любые сообщения об ошибках, обычно выводимые include
, подавляются путем добавления в него префикса @
.
Проверьте функцию stream_resolve_include_path, она выполняет поиск по тем же правилам, что и include().
Http://php.net/manual/en/function.stream-resolve-include-path.php
Вы также можете проверить наличие любых переменных, функций или классов, определенных во включаемом файле, и посмотреть, сработало ли включение.
if (isset($variable)) { /*code*/ }
ИЛИ
if (function_exists('function_name')) { /*code*/ }
ИЛИ
if (class_exists('class_name')) { /*code*/ }
file_exists
будет работать с проверкой, существует ли требуемый файл, когда он находится относительно текущего рабочего каталога, так как он отлично работает с относительными путями. Однако, если включаемый файл находился в другом месте ПУТИ, вам придется проверить несколько путей.
function include_exists ($fileName){
if (realpath($fileName) == $fileName) {
return is_file($fileName);
}
if ( is_file($fileName) ){
return true;
}
$paths = explode(PS, get_include_path());
foreach ($paths as $path) {
$rp = substr($path, -1) == DS ? $path.$fileName : $path.DS.$fileName;
if ( is_file($rp) ) {
return true;
}
}
return false;
}
file_exists()
работает с относительными путями, он также проверяет, существуют ли каталоги. Используйте is_file()
вместо:
if (is_file('./path/to/your/file.php'))
{
require_once('./path/to/your/file.php');
}
Я думаю, что правильный способ - это сделать:
if(file_exists(stream_resolve_include_path($filepath))){
include $filepath;
}
Это связано с тем, что в документации говорится, что stream_resolve_include_path
разрешает "имя файла по пути включения в соответствии с теми же правилами, что и fopen()/include".
Некоторые люди предлагали использовать is_file
или is_readable
, но это не для общего случая использования , потому что в общем случае, если файл заблокирован или недоступен по какой-либо причине после того, как file_exists возвращает TRUE, это то, что вам нужно заметить с очень уродливым сообщение об ошибке прямо на конечных пользователях, или в противном случае вы можете столкнуться с неожиданным и необъяснимым поведением позже с возможной потерей данных и тому подобными вещами.