递归搜索目录并列出x个最新文件(基于服务器上的创建日期)



好吧,我不完全理解我在这里做什么,所以我想我应该得到一些关于我的代码的反馈。

尝试递归搜索服务器上的特定文件夹,并返回添加的30个最新*.jpg图像(带有完整的文件路径)。

目前,我的当前代码给了我(我假设)时间戳(它们看起来都像一个由10个数字组成的字符串),实际上,我似乎只得到了我期望的30个数字中的22个。我看到了另一篇使用directoryIteratorIterator的帖子,但我无法为我的服务器升级我的PHP版本,而且我找不到很多关于这方面的清晰文档。

希望有人能引导我朝着正确的方向前进。

<?php
function get30Latest(){
    $files = array();
    foreach (glob("*/*.jpg") as $filename) {  //I assume "*/*.jpg" would start from the root of the server and go through each directory looking for a match to *.jpg and add to $files array
        $files[$filename] = filemtime($filename);
    }
    arsort($files); //I may not need this since I'm looking to sort by earliest to latest (among the 30 newest images)
    $newest = array_slice($files, 0, 29);  //This should be the first 30 I believe.
    foreach ($newest as $file){ //Assuming I would loop through the array and display the full paths of these 30 images
        echo $file . "</br>"; //Returns something similar to "1451186291, 1451186290, 1451186290, etc..."
    }
}
?>

你走得很好。这应该对你有用:

首先,我们创建一个RecursiveDirectoryIterator,并将其传递给RecursiveIteratorIterator,这样我们就有了一个迭代器来递归迭代指定路径的所有文件。我们用RegexIterator过滤掉除*.jpg文件之外的所有内容。

现在我们可以用iterator_to_array()将迭代器转换成一个数组,这样我们就可以随心所欲地对数组进行排序。我们将usort()filectime()结合使用,这样我们可以比较文件的创建日期并以此进行排序。

最后,我们可以用array_slice()对30个最新的文件进行切片,我们就完成了。循环浏览文件并显示它们。

代码:

<?php
    $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("your/path"));
    $rgIt = new RegexIterator($it, "/^.+.jpg$/i");
    $files = iterator_to_array($rgIt);
    usort($files, function($a, $b){
      if(filectime($a) == filectime($b))
        return 0;
      return filectime($a) > filectime($b) ? -1 : 1;
    });
    $files = array_slice($files, 0 , 30);
    foreach($files as $v)
      echo $v . PHP_EOL;
?>

我认为你可能想做的是让你的函数更通用,以防你想把它的函数用于其他用途或只是简单地更改它。你不必创建get10Latest()get25Latest()等。这只是一个简单的类,包含了你需要获取和返回的所有脚本。使用你想要的,方法是按使用顺序排列的,所以你可以拿出方法的内脏来创建一个大函数:

class   FetchImages
    {
        private $count  =   30;
        private $arr    =   array();
        private $regex  =   '';
        public  function __construct($filter = array('jpg'))
            {
                // This will create a simple regex from the array of file types ($filter)
                $this->regex    =   '.+.'.implode('|.+.',$filter);
            }
        public  function getImgs($dir = './')
            {
                // Borrowed from contributor notes from the RecursiveDirectoryIterator page
                $regex      =   new RegexIterator(
                                new RecursiveIteratorIterator(
                                new RecursiveDirectoryIterator($dir)),
                                '/^'.$this->regex.'$/i',
                                RecursiveRegexIterator::GET_MATCH);
                // Loop and assign datetimes as keys,
                // You don't need date() but it's more readable for troubleshooting
                foreach($regex as $file)
                    $this->arr[date('YmdHis',filemtime($file[0]))][]    =   $file[0];
                // return the object for method chaining
                return $this;
            }
        public  function setMax($max = 30)
            {
                // This will allow for different returned values
                $this->count    =   $max;
                // Return for method chaining
                return $this;
            }
        public  function getResults($root = false)
            {
                if(empty($this->arr))
                    return false;
                // Set default container
                $new    =   array();
                // Depending on your version, you may not have the "SORT_NATURAL"
                // This is what will sort the files from newest to oldest
                // I have not accounted for empty->Will draw error(s) if not array
                krsort($this->arr,SORT_NATURAL);
                // Loop through storage array and make a new storage
                // with single paths
                foreach($this->arr as $timestamp => $files) {
                    for($i = 0; $i < count($files); $i++)
                        $new[]  =   (!empty($root))? str_replace($root,"",$files[$i]) : $files[$i];
                }
                // Return the results
                return (!$this->count)? $new : array_slice($new,0,$this->count);
            }
    }
// Create new instance. I am allowing for multiple look-up
$getImg =   new FetchImages(array("jpg","jpeg","png"));
// Get the results from my core folder
$count  =   $getImg ->getImgs(__DIR__.'/core/')
                    // Sets the extraction limit "false" will return all
                    ->setMax(30)
                    // This will strip off the long path
                    ->getResults(__DIR__);
print_r($count);

我真的不需要一个巨大的、灵活的函数类。此功能将始终输出30张最新的图像。如果我理解正确的话,您将时间戳作为关键字分配给数组中的每个文件,然后使用krsort按关键字排序?我正试图提取这些片段,以便获得一个带有时间戳的文件数组,从最新到最旧排序,然后将数组切片为前30个。这里只是一个快速的尝试作为一个谈话要点(无论如何都不完整)。目前它只输出一个文件几百次:

<?php
function get30Latest(){
    $directory = new RecursiveDirectoryIterator('./');
    $iterator = new RecursiveIteratorIterator($directory);
    $regex = new RegexIterator($iterator, '/^.+.jpg$/i', RecursiveRegexIterator::GET_MATCH);
    foreach($regex as $file){
        $tmp->arr[date('YmdHis',filemtime($file[0]))][] = $file[0];
        krsort($tmp->arr,SORT_NATURAL);
        foreach($tmp->arr as $timestamp => $files) {
            for($i = 0; $i < count($files); $i++)
                $new[] = (!empty($root))? str_replace($root,"",$files[$i]) : $files[$i];
            echo $new[0] . "</br>";  //this is just for debugging so I can see what files
                                     //are showing up.  Ideally this will be the array I'll
                                     //pull the first 30 from and then send them off to a
                                     //thumbnail creation function
        }
    }
}
?>

最新更新