Проверьте, существует ли файл где-либо в пути включения
Я пишу функцию автозагрузки, и во внутренней логике он хотел бы проверить, существует ли какой-то файл где-то на пути до его включения.
Это логика:
Если файл с именем $className'.specialversion.php'
существует в любом месте включенного пути, включите его. В противном случае пусть другие автозагрузчики позаботятся о включении файла для этого класса.
На данный момент я просто делаю: @include($calculatedPath);
Я не уверен, что это хороший подход к включению и подавлению ошибки. Я бы предпочел проверить, существует ли файл (где-то на пути включения) до его включения.
Мой вопрос:
- Можно ли проверить наличие файла в любом месте пути include?
- Это действительно проблематично сделать
@include($calculatedPath);
?
Edit
Важный акцент: я не знаю, где должен быть файл. Я просто хочу знать, существует ли она в одной из каталогов в пути include. Поэтому я не могу просто сделать file_exists()
или что-то в этом роде.
Ответы
Ответ 1
Начиная с PHP 5.3.2 существует возможность использовать функцию stream_resolve_include_path()
, целью которой является
Разрешить [a] имя файла по пути включения в соответствии с теми же правилами, что и fopen()/include().
Если файл существует на одном из включенных путей, то этот путь (включая имя файла) будет возвращен. В противном случае (т.е. Файл не был включен ни в один из включенных путей), он вернет FALSE
.
Относясь к вашим потребностям, ваш автозагрузчик может выглядеть примерно так:
function my_autoloader($classname) {
$found = stream_resolve_include_path($classname . '.specialversion.php');
if ($found !== FALSE) {
include $found;
}
}
Ответ 2
Вам следует избегать оператора подавления ошибок @
.
function autoload($class) {
// Build path (here is an example).
$path = DIR_CLASSES .
strtollower(str_replace('_', DIRECTORY_SEPARATOR, $class)) .
'.class.php';
if (file_exists($path)) {
include $path;
}
}
spl_autoload_register('autoload');
$front = new Controller_Front;
// Loads "application/classes/controller/front.class.php" for example.
Update
Важный акцент: я не знаю, где должен быть файл, я просто хочу знать, существует ли он в одном из каталогов в пути include. Поэтому я не могу просто делать file_exists или что-то вроде этого
Если ваш класс может быть в нескольких каталогах, вы можете...
- Чтобы ваша функция автозагрузки проходила их все, вы искали класс. Я бы не рекомендовал это.
- Переименуйте свои классы, чтобы иметь имя, которое легко сопоставляется с файловым путем, например, в приведенном выше примере.
Если вы решите пересечь все папки, ищущие класс, и это станет узким местом (сравните его), вы можете извлечь выгоду из кэширования имени класса для сопоставления местоположения файла.
Ответ 3
Я бы использовал file_exists
, а не включил предупреждения.
Затем вам нужно будет проходить через include_path
:
$paths = explode(';', get_include_path());
foreach($paths as $p){
if(file_exists($p . '/' . $calculatedPath)){
include $p . '/' . $calculatedPath;
break;
}
}
Ответ 4
Я написал функцию, которая может хорошо ее протестировать
function fileExists($file) {
if(function_exists('stream_resolve_include_path'))
return stream_resolve_include_path($file);
else {
$include_path = explode(PATH_SEPARATOR, get_include_path());
foreach($include_path as $path)
if(file_exists($path.DS.$file))
return true;
return false;
}
}
Ответ 5
Как простое разрешение, вы должны протестировать в SPL-функции file_get_contents(), установив второй аргумент в TRUE.
- Rolf