Seleccione un archivo aleatorio usando OPENDIR()
Frecuentes
Visto 1,998 veces
-4
Yo he tratado:
function random_pic($dir = '../myfolder') {
$files = opendir($dir . '/*.*');
$file = array_rand($files);
return $files[$file];
}
This function works using glob()
but not opendir.
This returns a failed to open directory error. I guess opendir cannot accept things like *.*
? Is it possible to select all files in a folder and randomly choose one?
2 Respuestas
4
El opendir()
function wont return a list of files/folders. It will only open a handle that can be used by closedir()
, readdir()
or rewinddir()
. The correct usage here would be glob()
, but as I see that you don't want that, you could also use 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];
?>
I'd happily do the timing to see if this takes longer or if glob()
takes longer after you admit that I'm not "wrong."
Respondido 14 Jul 16, 21:07
As happy that I am that you seek my admittance of whether I deem you right or wrong, benchmark results reveal you to be wrong. Thanks for your input. - nórdico
What do you mean benchmark results reveal me wrong... That makes no sense. You can't use opendir()
here. Your options are scandir()
y glob()
. Before I continue to proceed, is that what we're arguing about (just so I know). Do you think opendir()
is useable here? The other alternative is readdir()
which would use the handle created by opendir()
, pero opendir()
still doesn't return the array of files... - Jeremy
My first language is english (which it really shouldn't matter if it isnt...). My problem was that what you've said had no relevance to what I'm trying to explain to you. You've also ignored what I asked, could you explain please? - Jeremy
@Norse: Guess what? Messing up faster is still just messing up. Performance comparisons mean precisely nada unless both programs work correctly. And since yours obviously doesn't, any comparison is meaningless. It doesn't matter how long it takes to do the wrong thing. - chao
I did downvote, as I didn't feel this answered the question, nor did it help me when I had the same question. I don't really care about quarrel you and op had, I simply want the best answer. I modified my answer to attempt to show more results after spending a few hours on these methods today, simply to test out what would work best. In the end, I like opendir
and as noted, had little difference from scandir. Have a great weekend. - SpYk3HH
0
The following 2 methods make use of
opendir
to quickly read through a directory and return a random file or directory.
- All Benchmarks done use CI3 and are average of 100 pulses.
Using WAMP on Win10 Intel i54460 w/ 16GB RAM
Get Random File:
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
Get 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;
}
Ú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
Use in Combo Like:
$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. */
Just a Note about
glob
&&scandir
.
I made alternate versions of thegetRandomDir
using each.
Usarscandir
had very little if any difference in benchmarks (from -.001 to +.003)
Usarglob
was quite noticeably slower! Anywhere from +.5 to +1.100 difference on each call.
Respondido 16 Jul 16, 21:07
..assuming you dv'd me? why? also this answer is deceptive in that opendir isn't really the function which is selecting the random file - Jeremy
@Jeremy Nothing deceptive about it. It does as OP asked and as I was seeking to do. It DOES use opendir, as is intended by opendir. Your answer simply does not. opendir is meant to open a directory for reading then use readdir for info needed, then close and go. It's really quite simple and benchmarks quite nicely. Sorry your old answer didn't reach a correct conclusion for this question and certainly didn't help me when seeking this answer. - SpYk3HH
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas php opendir or haz tu propia pregunta.
And... what's wrong with using
glob()
? Also, in order to use the...dir()
functions, you need to use thescandir()
función en este caso. - jeremyOkay? Except you're using it for the wrong thing... - jeremy
opendir
makes no sense in your code. It returns a resource, as per the relevant manual entry. You're callingarray_rand
on it. Obviously, that won't work because a resource is not an array. I somehow doubt you "benchmarked" the difference betweenopendir
yglob
on the same task because that's like comparing apples to smallpox. They aren't the same. - rdlowreyupvote for apples to smallpox comparison. opendir is probably not going to be faster, but it may be slightly more memory efficient since you wouldn't have to generate the whole array. - nneonneo