Проверьте, существует ли включение (или требуется) - PullRequest
41 голосов
/ 12 февраля 2010

Как проверить, существует ли include / require_once перед его вызовом, я пытался поместить его в блок ошибок, но PHP это не понравилось.

Я думаю, file_exists() будет работать с некоторыми усилиями, однако это потребует полного пути к файлу, и относительное включение не может быть легко передано в него.

Есть ли другие способы?

Ответы [ 6 ]

55 голосов
/ 12 февраля 2010

Полагаю, file_exists работает с относительными путями, хотя вы также можете попробовать что-то подобное ...

if(!@include("script.php")) throw new Exception("Failed to include 'script.php'");

... само собой разумеется, вы можете заменить исключение любым методом обработки ошибок по вашему выбору. Идея заключается в том, что if -статист проверяет, может ли файл быть включен, и любые сообщения об ошибках, обычно выводимые include, подавляются префиксом @.

.
9 голосов
/ 29 октября 2012

Проверьте функцию stream_resolve_include_path, поиск выполняется по тем же правилам, что и include ().

http://php.net/manual/en/function.stream-resolve-include-path.php

9 голосов
/ 29 мая 2012

Вы также можете проверить наличие любых переменных, функций или классов, определенных в файле включения, и посмотреть, сработало ли включение.

if (isset($variable)) { /*code*/ }

OR

if (function_exists('function_name')) { /*code*/ }

OR

if (class_exists('class_name')) { /*code*/ }
6 голосов
/ 12 февраля 2010

file_exists будет работать с проверкой, существует ли требуемый файл, если он относительно текущего рабочего каталога, так как он отлично работает с относительными путями. Однако, если файл включения был в другом месте в PATH, вам нужно будет проверить несколько путей.

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;
}
5 голосов
/ 12 февраля 2010

file_exists() работает с относительными путями, он также проверяет, существуют ли каталоги. Используйте is_file() вместо:

if (is_file('./path/to/your/file.php'))
{
    require_once('./path/to/your/file.php');
}
0 голосов
/ 26 апреля 2017

Я думаю, что правильный путь это сделать:

if(file_exists(stream_resolve_include_path($filepath))){
  include $filepath;    
}

Это потому, что документация говорит, что stream_resolve_include_path разрешает "имя файла по пути включения в соответствии с теми же правилами, что и fopen () / include."

Некоторые люди предложили использовать is_file или is_readable, но , что не для общего случая , потому что в общем случае, если файл заблокирован или недоступен по какой-либо причине после того, как file_exists вернет TRUE Это то, что вы должны заметить с очень уродливым сообщением об ошибке прямо на лице конечного пользователя, или иначе вы открыты для неожиданного и необъяснимого поведения позже с возможной потерей данных и тому подобного.

...