Test whether a file exists anywhere in the include

2020-07-06 05:29发布

I'm writing an autoload function and in the inner logic of it would like to test whether a certain file exists somewhere in the path prior to including it.

This is the logic:

If a file named $className'.specialversion.php' exists anywhere in the include path include it. Otherwise, let other autoloaders take care of including a file for this class.

At the moment I just do: @include($calculatedPath);

I'm not sure if it's a good approach to include and suppress the error. I would rather check if the file exists (somewhere in the include path) prior to including it.

My question is:

  • Can I test for existence of a file anywhere in the include path?
  • Is it really problematic to do @include($calculatedPath);?

Edit

An important accent: I don't know where the file should be. I just want to know whether it exists in one of the directories in the include path. So I can't just do file_exists() or something like that.

标签: php include
5条回答
成全新的幸福
2楼-- · 2020-07-06 05:47

As of PHP 5.3.2 there is the option to use the stream_resolve_include_path() function whose purpose is to

Resolve [a] filename against the include path according to the same rules as fopen()/include() does.

If the file exists on one of the include paths, then that path (including the file name) will be returned. Otherwise (i.e. the file was not on any of the include paths) it will return FALSE.

Relating this to your needs, your autoloader might look something like:

function my_autoloader($classname) {
    $found = stream_resolve_include_path($classname . '.specialversion.php');
    if ($found !== FALSE) {
        include $found;
    }
}
查看更多
3楼-- · 2020-07-06 05:55

I've written a function that can test it nicely

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;
    }
}
查看更多
Animai°情兽
4楼-- · 2020-07-06 05:56

You should avoid the error supressor operator @.

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

An important accent: I don't know where the file should be, I just want to know whether it exists in one of the directories in the include path. So I can't just do file_exists or something like this

If your class could be in a number of directories, you could...

  • Have your autoload function traverse them all, looking for the class. I would not recommend this.
  • Rename your classes to have a name that easily maps to a file path, like in the example code above.

If you do decide to traverse all folders looking for the class, and it becomes a bottleneck (benchmark it), you could benefit from caching the class name to file location mapping.

查看更多
混吃等死
5楼-- · 2020-07-06 06:00

I would use file_exists rather than a warnings-suppressed include.

Then you'll have to iterate through the include_path:

$paths = explode(';', get_include_path());
foreach($paths as $p){
    if(file_exists($p . '/' . $calculatedPath)){
        include $p . '/' . $calculatedPath;
        break;
    }
}
查看更多
够拽才男人
6楼-- · 2020-07-06 06:02

As a simple resolution, you should a test within the SPL-function file_get_contents() by setting the second argument to TRUE.

--Rolf

查看更多
登录 后发表回答