Выберите произвольный файл, используя OPENDIR ()

Я пытался:

function random_pic($dir = '../myfolder') { $files = opendir($dir . '/*.*'); $file = array_rand($files); return $files[$file]; } 

Эта функция работает с использованием glob() но не opendir.

Это возвращает не удалось открыть ошибку каталога. Я думаю, opendir не может принимать такие вещи, как *.* ? Можно ли выбрать все файлы в папке и случайно выбрать один?

Функция opendir() возвращает список файлов / папок. Он откроет дескриптор, который может быть использован closedir() , readdir() или rewinddir() . Правильное использование здесь будет glob() , но поскольку я вижу, что вы этого не хотите, вы также можете использовать scandir() следующим образом:

 <?php $path = "./"; $files = scandir($path); shuffle($files); for($i = 0; ($i < count($files)) && (!is_file($files[$i])); $i++); echo $files[$i]; ?> 

Я бы с удовольствием проверил время, чтобы узнать, требуется ли это дольше, или если glob() занимает больше времени после того, как вы признаете, что я не «ошибаюсь».

Следующие 2 метода используют opendir для быстрого чтения каталога и возврата случайного файла или каталога.


  • Все контрольные тесты используют CI3 и составляют в среднем 100 импульсов.
    Использование WAMP на Win10 Intel i54460 с 16 ГБ оперативной памяти

Получить случайный файл:

 function getRandomFile($path, $type=NULL, $contents=TRUE) { if (strpos($path, $_SERVER['DOCUMENT_ROOT']) === FALSE) $path = $_SERVER['DOCUMENT_ROOT'] . '/' . $path; if (is_dir($path)) { if ($dh = opendir($path)) { $arr = []; while (false !== ($file = readdir($dh))) { // not a directory if (!is_dir("$path/$file") && !preg_match('/^\.{1,2}$/', $file)) { // fits file type if(is_null($type)) $arr[] = $file; elseif (is_string($type) && preg_match("/\.($type)$/", $file)) $arr[] = $file; elseif (is_array($type)) { $type = implode('|', $type); if (preg_match("/\.($type)$/", $file)) $arr[] = $file; } } } closedir($dh); if (!empty($arr)) { shuffle($arr); $file = $arr[mt_rand(0, count($arr)-1)]; return empty($contents) ? $file : ($contents == 'path' ? "$path/$file" : file_get_contents($file)); } } } return NULL; } 

Используйте так же просто, как:

 // Benchmark 0.0018 seconds * $this->getRandomFile('directoryName'); // would pull random contents of file from given directory // Benchmark 0.0017 seconds * $this->getRandomFile('directoryName', 'php'); // |OR| $this->getRandomFile('directoryName', ['php', 'htm']); // one gets a random php file // OR gets random php OR htm file contents // Benchmark 0.0018 seconds * $this->getRandomFile('directoryName', NULL, FALSE); // returns random file name // Benchmark 0.0019 seconds * $this->getRandomFile('directoryName', NULL, 'path'); // returns random full file path 

Получить случайный каталог:

 function getRandomDir($path, $full=TRUE, $indexOf=NULL) { if (strpos($path, $_SERVER['DOCUMENT_ROOT']) === FALSE) $path = $_SERVER['DOCUMENT_ROOT'] . '/' . $path; if (is_dir($path)) { if ($dh = opendir($path)) { $arr = []; while (false !== ($dir = readdir($dh))) { if (is_dir("$path/$dir") && !preg_match('/^\.{1,2}$/', $dir)) { if(is_null($indexOf)) $arr[] = $file; if (is_string($indexOf) && strpos($dir, $indexOf) !== FALSE) $arr[] = $dir; elseif (is_array($indexOf)) { $indexOf = implode('|', $indexOf); if (preg_match("/$indexOf/", $dir)) $arr[] = $dir; } } } closedir($dh); if (!empty($arr)) { shuffle($arr); $dir = $arr[mt_rand(0, count($arr)-1)]; return $full ? "$path/$dir" : $dir; } } } return NULL; } 

Используйте так же просто, как:

 // Benchmark 0.0013 seconds * $this->getRandomDir('parentDirectoryName'); // returns random full directory path of dirs found in given directory // Benchmark 0.0015 seconds * $this->getRandomDir('parentDirectoryName', FALSE); // returns random directory name // Benchmark 0.0015 seconds * $this->getRandomDir('parentDirectoryName', FALSE, 'dirNameContains'); // returns random directory name 

Использование в Combo:

 $dir = $this->getRandomDir('dirName'); $file = $this->getRandomFile($dir, 'mp3', FALSE); // returns a random mp3 file name. // Could be used to load random song via ajax. 

одна линия

 /** getRandomFile(String) * Simple method for retrieving a random file from a directory **/ function getRandomFile($path, $type=NULL, $contents=TRUE) { if (strpos($path, $_SERVER['DOCUMENT_ROOT']) === FALSE) $path = $_SERVER['DOCUMENT_ROOT'] . '/' . $path; if (is_dir($path)) { if ($dh = opendir($path)) { $arr = []; while (false !== ($file = readdir($dh))) { if (!is_dir("$path/$file") && !preg_match('/^\.{1,2}$/', $file)) { if(is_null($type)) $arr[] = $file; elseif (is_string($type) && preg_match("/\.($type)$/", $file)) $arr[] = $file; elseif (is_array($type)) { $type = implode('|', $type); if (preg_match("/\.($type)$/", $file)) $arr[] = $file; } } } closedir($dh); if (!empty($arr)) { shuffle($arr); $file = $arr[mt_rand(0, count($arr)-1)]; return empty($contents) ? $file : ($contents == 'path' ? "$path/$file" : file_get_contents($file)); } } } return NULL; } /** getRandomDir(String) * Simple method for retrieving a random directory **/ function getRandomDir($path, $full=TRUE, $indexOf=NULL) { if (strpos($path, $_SERVER['DOCUMENT_ROOT']) === FALSE) $path = $_SERVER['DOCUMENT_ROOT'] . '/' . $path; if (is_dir($path)) { if ($dh = opendir($path)) { $arr = []; while (false !== ($dir = readdir($dh))) { if (is_dir("$path/$dir") && !preg_match('/^\.{1,2}$/', $dir)) { if(is_null($indexOf)) $arr[] = $file; if (is_string($indexOf) && strpos($dir, $indexOf) !== FALSE) $arr[] = $dir; elseif (is_array($indexOf)) { $indexOf = implode('|', $indexOf); if (preg_match("/$indexOf/", $dir)) $arr[] = $dir; } } } closedir($dh); if (!empty($arr)) { shuffle($arr); $dir = $arr[mt_rand(0, count($arr)-1)]; return $full ? "$path/$dir" : $dir; } } } return NULL; } /* This is only here to make copying easier. */ 

Просто примечание о glob && scandir .
Я использовал альтернативные версии getRandomDir используя каждый.
Использование scandir было очень мало, если какая-либо разница в тестах (от -.001 до +.003)
Использование glob было заметно медленнее! В любом месте от +5 до +1.100 разница на каждом вызове.