PHP не может найти первый файл в DIR, когда он называется "original.jpg"
У меня есть простая функция, которая возвращает правильный путь к изображению для отображения. Передается URL, который хранится для конкретной строки в моей БД. Основные функциональные возможности:
- Если URL имеет косую черту, это каталог; вернуть первый файл в этом каталоге. Если их нет, верните "изображение по умолчанию"
- Если 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);
}
3 ответа
Вы дважды вызываете 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 .. .