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

上記は機能しますが、反復を特定のフォルダーに制限する必要があります。このスクリプトは、「administrator」、「components」、「modules」、「plugins」、「templates」などの特定のサブフォルダー(つまり、Joomlaインストールの標準フォルダー)が必要な親フォルダーで開始されます。また、「index.php」のように、親フォルダーにいくつかのファイルがあることを期待しています。これらのファイルとフォルダーは反復する必要があります(率直に言って、これを書くと、親フォルダー自体が私のコードによって反復されているかどうかはわかりません!)。ただし、親フォルダーに、反復してはならない他のサブフォルダーが含まれている可能性があります。これらは、「mysub」や「myaddon.com」などの名前のサブドメインまたはアドオンドメインのサブフォルダーである可能性があります。通常のJoomlaインストールフォルダ以外のフォルダをスキップしたい理由は2つあります。1つは、他のフォルダー内のファイルについて知る必要がないことです。さらに、すべてのフォルダーを繰り返すと、500のエラーページが表示されるほど多くの時間とリソースがかかる可能性があります。

私の質問は、適切なフォルダーがイテレーションから除外され、イテレーションに含まれるようにするために、コードをどのように変更するのが最善かということです。Webでディレクトリの名前をチェックするイテレータの例を見てきましたが、2番目のレベルのフォルダ名(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

通常、 を使用しRecursiveIteratorIteratorて の「再帰性」を解決しRecursiveDirectoryIteratorます。Aは、すでに使い慣れている他のものと同じように使用できるRecursiveIteratorIteratorシンプルなものです。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

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 に答える
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 に答える