1

我正在尝试使用 PHP 递归目录迭代器来查找 php 和 html 文件,以便按日期列出这些文件。使用的代码如下:

        $filelist = array();
    $iterator = new RecursiveDirectoryIterator( $this->_jrootpath );
    foreach(new RecursiveIteratorIterator($iterator) as $file) {
        if ( !$file->isDir() ) {
            if ( preg_match( "/.(html|htm|php)$/", $file->getFilename() ) ) {
                $filelist[$file->getPathname()] = $file->getMTime();
            }
        }
    }
    arsort($filelist);
    foreach ($filelist as $key => $val) {
        $resultoutput .= '          <tr>
                                        <td class="filepath">'.$key.'</td>
                                        <td class="filedate">'.date("d-m-Y H:i:s",$val).'</td>
                                    </tr>';
    }

以上工作,但我需要将迭代限制到某些文件夹。该脚本将在父文件夹中开始,我希望其中有一些特定的子文件夹,例如“管理员”、“组件”、“模块”、“插件”和“模板”(换句话说,Joomla 安装的标准文件夹)。我还希望父文件夹中有一些文件,例如“index.php”。这些文件和文件夹应该被迭代(坦率地说,写这个我不确定父文件夹本身是否被我的代码迭代!)。但是,父文件夹可能还包含不应迭代的其他子文件夹。这些可以是子域或插件域的子文件夹,例如命名为“mysub”和“myaddon.com”。除了正常的 Joomla 安装文件夹之外,我想跳过任何文件夹有两个原因。一是我不需要知道其他文件夹中的文件。此外,迭代所有文件夹可能会花费大量时间和资源,以至于我得到 ​​500 个错误页面。

我的问题是如何最好地更改我的代码,以确保正确的文件夹被排除在迭代之外并包含在迭代中?我已经在网络上看到了检查目录名称的迭代器示例,但这对我帮助不够,因为我只需要检查二级文件夹名称(意味着只需要像 parent/secondlevel/noneedtocheck 这样的路径中的最高级别子文件夹/file.php)。

4

5 回答 5

1

不,不!你想要这样的东西:

<?php
class FilteredRecursiveDirectoryIterator extends FilterIterator
{   
    public function __construct($path)
    {
        parent::__construct(new RecursiveDirectoryIterator($path));
    }
    public function accept()
    {
        if($this->current()->isFile() and in_array($this->getExtention(), array('html', 'php')))
            return true;

        return false;
    }

    private function getExtention()
    {
        return end(explode('.', $this->current()->getFilename()));
    }
}

accept() 方法为您完成所有过滤。我还没有测试过这个,但我相信它很好;)

于 2010-01-15T14:15:24.240 回答
0

通常你使用 anRecursiveIteratorIterator来解决RecursiveDirectoryIterator. ARecursiveIteratorIterator只是一个简单Iterator的,可以像您可能已经熟悉的任何其他方法一样使用。这包括使用FilterIterator它。在 PHP 5.4 中看起来像这样(CallbackIterator是新的)

<?php
$directories = new CallbackIterator(
    new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator('path/to/directory')
    ),
    function($current) {
        return $current->isDir();
    }
);

foreach ($directories as $directory) {
    ...
}

对于 PHP <5.4,您需要CallbackIterator自己实现

<?php
class CallbackIterator extends FilterIterator
{
    private $callback;

    public function __construct(Traversable $iterator, $callback)
    {
        $this->callback = $callback;
    }

    public function accept()
    {
        return call_user_func($this->callback, $this->current());
    }
}
于 2012-11-28T23:24:33.887 回答
0

我将尝试以下方法:通过将迭代器放在一个函数中,我可以重复使用它来包含已知文件夹以构建结果数组。我仍然希望有一天我能找到一种解决方案,可以更优雅地使用 PHP 迭代器,而无需在我的方法中嵌套函数。

    $filelist = array();
    $filelist[$this->_jrootpath.DS.'index.php'] = date("d-m-Y H:i:s",filemtime($this->_jrootpath.DS.'index.php'));
    $filelist[$this->_jrootpath.DS.'index2.php'] = date("d-m-Y H:i:s",filemtime($this->_jrootpath.DS.'index2.php'));
    $joomlafolders = array( $this->_jrootpath.DS.'administrator', $this->_jrootpath.DS.'cache', $this->_jrootpath.DS.'components', $this->_jrootpath.DS.'images', $this->_jrootpath.DS.'includes', $this->_jrootpath.DS.'language', $this->_jrootpath.DS.'libraries', $this->_jrootpath.DS.'logs', $this->_jrootpath.DS.'media', $this->_jrootpath.DS.'modules', $this->_jrootpath.DS.'plugins', $this->_jrootpath.DS.'templates', $this->_jrootpath.DS.'tmp', $this->_jrootpath.DS.'xmlrpc' );
    foreach ( $joomlafolders as $folder ) {
        $iterator = new RecursiveDirectoryIterator( $folder );
        foreach(new RecursiveIteratorIterator($iterator) as $file) {
            if ( !$file->isDir() ) {
                if ( preg_match( "/.(html|htm|php)$/", $file->getFilename() ) ) {
                    $filelist[$file->getPathname()] = $file->getMTime();
                }
            }
        }
    }
    arsort($filelist);
    foreach ($filelist as $key => $val) {
        $resultoutput .= '          <tr>
                                        <td class="filepath">'.$key.'</td>
                                        <td class="filedate">'.date("d-m-Y H:i:s",$val).'</td>
                                    </tr>';
    }
于 2009-12-13T20:32:09.110 回答
0

您可以尝试使用RecursiveRegexIterator

编辑这是您使用 RecursiveRegexIterator 的示例:

$filelist = array();
$iterator = new RecursiveDirectoryIterator( $this->_jrootpath );
foreach(new RecursiveRegexIterator($iterator, '/\.(html|htm|php)$/') as $file) {
    if ( !$file->isDir() ) {
        $filelist[$file->getPathname()] = $file->getMTime();
    }
}
arsort($filelist);
foreach ($filelist as $key => $val) {
    $resultoutput .= '                      <tr>
                                                                            <td class="filepath">'.$key.'</td>
                                                                            <td class="filedate">'.date("d-m-Y H:i:s",$val).'</td>
                                                                    </tr>';
}

顺便说一句,它看起来$resultoutput还没有创建。在这种情况下,您应该在某处将其创建为空字符串...

EDIT2:哎呀,这并不能真正回答您的问题。出于某种原因,我认为这只是关于递归的东西。这只是循环文件的更优雅的解决方案,但它不能解决您的问题,抱歉。您可能应该将其与其他答案之一结合起来。

于 2009-12-12T22:10:27.733 回答
0
    $filelist = array();

// 创建一个被排除的数组 $excludeDirs= array("/var/www/joomla/admin/");

    $iterator = new RecursiveDirectoryIterator( $this->_jrootpath );
    foreach(new RecursiveIteratorIterator($iterator,RecursiveIteratorIterator::CHILD_FIRST) as $file) {
    if($file->getPathname() == excludeDirs[0])
       continue;
    if ( !$file->isDir() ) {
                    if ( preg_match( "/.(html|htm|php)$/", $file->getFilename() ) ) {
                            $filelist[$file->getPathname()] = $file->getMTime();
                    }
            }
    }
    arsort($filelist);
    foreach ($filelist as $key => $val) {
            $resultoutput .= '<tr>
            <td class="filepath">'.$key.'</td>
           <td class="filedate">'.date("d-m-Y H:i:s",$val).'</td>
           </tr>';
    }
于 2009-12-12T22:20:13.470 回答