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

时间:2015-12-29 04:41:45

标签: php file recursion directory

好的,我不完全理解我在这里做的事情,所以我想我会对我的代码得到一些反馈。

尝试以递归方式搜索我服务器上的特定文件夹,并返回添加的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..."
    }
}
?>

3 个答案:

答案 0 :(得分:1)

我认为你可能想做的是让你的功能更加通用,因为你想将它的功能用于其他用途,或者只是简单地改变它。您不必再创建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);

答案 1 :(得分:1)

你的方式很好。这应该适合你:

首先,我们创建一个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;

?>

答案 2 :(得分:0)

我真的不需要一个庞大,灵活的功能类。此功能将始终输出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
        }
    }

}
?>