Seleccione un archivo aleatorio usando OPENDIR()

Yo he tratado:

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

Esta función funciona usando glob() pero no opendir.

Esto devuelve un error al abrir el directorio. Supongo que opendir no puede aceptar cosas como *.*? ¿Es posible seleccionar todos los archivos en una carpeta y elegir uno al azar?

preguntado el 25 de agosto de 12 a las 06:08

Y... ¿qué hay de malo en usar glob()? Asimismo, para utilizar el ...dir() funciones, es necesario utilizar el scandir() función en este caso. -

¿Bueno? Excepto que lo estás usando para algo incorrecto... -

opendir no tiene sentido en su código. Devuelve un recurso, según la entrada manual correspondiente. estas llamando array_rand en eso. Obviamente, eso no funcionará porque un recurso no es una matriz. De alguna manera dudo que hayas "comparado" la diferencia entre opendir y glob en la misma tarea porque eso es como comparar manzanas con viruela. No son lo mismo. -

voto a favor de las manzanas para la comparación de la viruela. opendir probablemente no será más rápido, pero puede ser un poco más eficiente en cuanto a la memoria, ya que no tendría que generar toda la matriz. -

2 Respuestas

El opendir() La función no devolverá una lista de archivos/carpetas. Solo abrirá un mango que puede ser utilizado por closedir(), readdir() or rewinddir(). El uso correcto aquí sería glob(), pero como veo que no quieres eso, también podrías usar scandir() como el siguiente:

<?php
$path = "./";

$files = scandir($path);
shuffle($files);

for($i = 0; ($i < count($files)) && (!is_file($files[$i])); $i++);

echo $files[$i];
?>

Felizmente haría el tiempo para ver si esto lleva más tiempo o si glob() toma más tiempo después de admitir que no estoy "equivocado".

Respondido 14 Jul 16, 21:07

Tan feliz que estoy de que busques mi admisión de si te considero correcto o incorrecto, los resultados de referencia revelan que estás equivocado. Gracias por tu contribución. - nórdico

¿A qué te refieres con los resultados de referencia que me revelan mal? Eso no tiene sentido. no puedes usar opendir() aquí. Tus opciones son scandir() y glob(). Antes de continuar, es sobre eso que estamos discutiendo (solo para que lo sepa). Tu crees opendir() es utilizable aquí? La otra alternativa es readdir() que usaría el identificador creado por opendir(), pero opendir() todavía no devuelve la matriz de archivos... - Jeremy

Mi primer idioma es el inglés (que realmente no debería importar si no lo es...). Mi problema fue que lo que dijiste no tenía relevancia para lo que estoy tratando de explicarte. También has ignorado lo que te pregunté, ¿podrías explicarme por favor? - Jeremy

@Norse: ¿Adivina qué? Echar a perder más rápido sigue siendo solo estropear. Las comparaciones de rendimiento significan precisamente nada a menos que ambos programas funcionen correctamente. Y como el tuyo obviamente no lo hace, cualquier comparación no tiene sentido. No importa cuánto tiempo lleve hacer algo incorrecto. - chao

Voté a la baja, ya que no sentí que esto respondiera a la pregunta, ni me ayudó cuando tenía la misma pregunta. Realmente no me importa la pelea que tuvisteis con op, simplemente quiero la mejor respuesta. Modifiqué mi respuesta para intentar mostrar más resultados después de dedicar algunas horas a estos métodos hoy, simplemente para probar qué funcionaría mejor. en fin me gusta opendir y como se señaló, tenía poca diferencia con scandir. Ten un excelente fin de semana. - spYk3HH

Los siguientes 2 métodos hacen uso de opendir para leer rápidamente un directorio y devolver un archivo o directorio aleatorio.


  • Todos los puntos de referencia realizados utilizan CI3 y tienen un promedio de 100 pulsos.
    Uso de WAMP en Win10 Intel i54460 con 16 GB de RAM

Obtener archivo aleatorio:

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;
}

Úselo tan simple como:
//  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

Obtener directorio aleatorio:

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;
}

Úselo tan simple como:
//  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

Usar en combo como:

$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.

linea sola

/** 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.   */

Solo una nota sobre glob && scandir.
Hice versiones alternativas del getRandomDir usando cada uno.
Usar scandir tuvo muy poca o ninguna diferencia en los puntos de referencia (de -.001 a +.003)
Usar glob fue notablemente más lento! En cualquier lugar de +.5 a +1.100 de diferencia en cada llamada.

Respondido 16 Jul 16, 21:07

..suponiendo que me dv'd? ¿por qué? también esta respuesta es engañosa porque opendir no es realmente la función que selecciona el archivo aleatorio: Jeremy

@Jeremy Nada engañoso al respecto. Hace lo que OP pidió y lo que buscaba hacer. SÍ usa opendir, como pretende opendir. Tu respuesta simplemente no. opendir está destinado a abrir un directorio para leer, luego use readdir para obtener la información necesaria, luego cierre y listo. Es realmente bastante simple y los puntos de referencia son bastante buenos. Lo siento, su respuesta anterior no llegó a una conclusión correcta para esta pregunta y ciertamente no me ayudó cuando busqué esta respuesta. - spYk3HH

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.