当命名为'original.jpg'时,PHP无法在目录中找到第一个文件


PHP Can't Find First File In DIR When It's Named 'original.jpg'

我有一个简单的函数,它返回要显示的有效图像路径。它被传递给数据库中存储的特定行的URL。基本功能是:

  • 如果URL后面有一个斜杠,那就是一个目录;返回该目录中的第一个文件。如果没有,返回"default image"
  • 如果URL是图片,请检查它是否存在,否则使用第一条规则。

它工作完美,除了如果文件夹只包含一个名为'original.jpg'的文件,它显示默认图像。如果我添加另一个文件,它可以使用'original.jpg'。如果我将其重命名为"original.jpeg"或"ori.jpg"(或更短),它就可以工作了。这是我遇到的唯一一个有这种行为的文件名。

function displayFile($file){
    $imgPath = "./img/path/";
    // If folder was specified or file doesn't exists; use first available file
    if( substr($file, -1) == '/' || !file_exists($imgPath . $file) ){
        // Extract base path
        $file = strstr( $file, '/', true );
        $handle = opendir($imgPath . $file);
        $entry = readdir($handle);
        $firstFile = '';
        while (false !== ($entry = readdir($handle))) {
            if( substr($entry, 0, 1) != '.' ){
                $firstFile = $entry;
                break; // This break isn't the problem
            }
        }
        // No file found; use default
        if( $firstFile == '' ){ return $imgPath . "paw.png"; }
        // Found a file to use
        else{ return $imgPath . $file . '/' . $firstFile; }
    } else {
        // File name is valid; use it
        return $imgPath . $file;
    }
    closedir($imgPath);
}

你调用了两次readdir,基本上总是跳过第一个条目。

$entry = readdir($handle);

您执行了许多不必要的操作来检索文件。

这是你的函数的修改版本,它应该像预期的那样工作,它很短:

function displayFile($entry) {
    $imgPath = "./img/path/";
    $entry = implode('/', explode('../', $entry));
    $path = $imgPath.$entry;
    switch(true) {
        case is_file($path) : 
         return $path;
         break;
        case (is_dir($path) AND !is_file($path)) :
         $files = array_filter(glob($path."/*"), 'is_file');
         if(!empty($files)) {
             return $path . basename(array_values($files)[0]);
         }
         break;
    }
    return $imgPath . 'paw.png';
}

@knrdk是绝对正确的,但要解释这种看似不稳定的行为:它有时起作用而有时不起作用的原因是排序。将功能缩小到:

function displayFile($file){
  $imgPath = "./img/path/";
  $file = strstr( $file, '/', true );
    $handle = opendir($imgPath . $file);
    $entry = readdir($handle);
    while (false !== ($entry = readdir($handle))) {
        echo $entry . ' ';    
    }
closedir($imgPath);

说明

行为
/* folder/[1.jpg] */
displayFile('folder'); // Output: . 1.jpg
/* folder/[original.jpg] */
displayFile('folder'); // Output: . ..
/* folder/[original.jpeg] */
displayFile('folder'); // Output: original.jpg .
// Not entirely sure why that's different, but there it is
/* folder/[1.jpg, original.jpg] */
displayFile('folder'); // Output: original.jpg .. .