4

再帰的で、すべてのファイルとディレクトリ/サブディレクトリを表示する単純なディレクトリ イテレータ。

特定のファイル タイプを除外する組み込み関数が表示されません。たとえば、次の例では.jpg.png、 などの画像関連ファイルを出力したくありません。アドバイスを求めて、これを行うにはいくつかの方法があることを知っています。どちらが良いでしょう。

$scan_it = new RecursiveDirectoryIterator("/example_dir");

 foreach(new RecursiveIteratorIterator($scan_it) as $file) {

  echo $file;
  }
4

7 に答える 7

13

更新: わかりました、私はばかです。PHP には、このためのビルトインがあります。pathinfo()

これを試して:

$filetypes = array("jpg", "png");
$filetype = pathinfo($file, PATHINFO_EXTENSION);
if (!in_array(strtolower($filetype), $filetypes)) {
  echo $file;
}

元の回答:

ファイル名で実行substr()して、除外するファイルタイプの拡張子と一致するかどうかを確認してください。

$scan_it = new RecursiveDirectoryIterator("/example_dir");

foreach(new RecursiveIteratorIterator($scan_it) as $file) {
  if (strtolower(substr($file, -4)) != ".jpg" && 
      strtolower(substr($file, -4)) != ".jpg") {
    echo $file;
  }
}

正規表現を使用して簡単にすることができます。

if (!preg_match("/\.(jpg|png)*$/i", $file, $matches)) {
   echo $file;
}

配列を使用して、ファイルの種類を追跡することもできます。

$filetypes = array("jpg", "png");
if (!preg_match("/\.(" . implode("|", $filetypes) . ")*$/i", $file, $matches)) {
   echo $file;
}
于 2011-08-21T22:13:35.027 に答える
2

元の回答のクロス投稿(この質問にもあり ます) --

globiterator に変換することは、 custom を記述するよりも簡単に prefilter するようですFilterIterator。また、反復中に各項目をステップスルーし、それを無視するだけであることに注意してくださいFilterIterator。一方、glob はそうではないようです。 ただしglob除外するのではなく含めるように見えるため、シナリオに合わない場合があります。

プレフィルターなし:

$dir_iterator = new DirectoryIterator($dir);
$paginated = new LimitIterator($dir_iterator, $page * $perpage, $perpage);

グロブ プレフィルター:

$dir_glob = $dir . '/*.{jpg,gif,png}';

$dir_iterator = new ArrayObject(glob($dir_glob, GLOB_BRACE)); // need to get iterator
$dir_iterator = $dir_iterator->getIterator();
$paginated = new LimitIterator($dir_iterator, $page * $perpage, $perpage);

次に、あなたのことをしてください:

foreach ($paginated as $file) { ... }

このDirectoryIterator例の場合、$fileは のインスタンスになりますがSplFileInfoglob例は単なるディスク パスであることに注意してください。


FilterIterator拡張例

class ExtensionFilterIterator extends FilterIterator {
    private $filter;

    public function __construct(Iterator $iterator , $filter) {
        parent::__construct($iterator);
        $this->filter = $filter;
    }

    // the meat and potatoes
    public function accept() {
        $current = $this->getInnerIterator()->current();

        ### global $counter;
        ### print_r(array($counter++, $current)); // this proves it goes through the whole thing, even with limit

    // do your comparison


        // assume path
        if( is_string($current) ) {
            $extension = end( explode('.', $current) );
        }
        // assume DirectoryIterator
        else {
            // $ext = $fileinfo->getExtension(); // http://www.php.net/manual/en/class.splfileinfo.php
            $extension = pathinfo($current->getFilename(), PATHINFO_EXTENSION); // < PHP 5.3.6 -- http://www.php.net/manual/en/splfileinfo.getextension.php
        }

        return !    in_array($extension,$this->filter);
    }
}

使用法:

$dir_iterator = new ExtensionFilterIterator(new DirectoryIterator($dir), array('gif', 'jpg', 'png'));
$paginated = new LimitIterator($dir_iterator, $page * $perpage, $perpage);
于 2013-01-31T02:38:45.717 に答える
1

私は例が大好きで、ここにその1つがあります

拡張機能をフィルタリングする方法を探していました。拡張機能を含めたり除外したりできます。

<?php

$dir_iterator = new RecursiveDirectoryIterator("/path");
$iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST);
// could use CHILD_FIRST if you so wish

foreach ($iterator as $file) {
    echo $file, "\n";
}

?>

$file は SplFileInfo クラスになるため、強力な機能を非常に簡単に実行できます。

<?php


foreach ($iterator as $file) {
    if ($file->isFile()) {
        echo $file->getExtension(); //By this you are king and you can access more functions of SplFileInfo
    }
}



?>
于 2016-01-08T16:38:42.813 に答える
1

他の回答を拡張すると、特殊化することで、よりクリーンな方法でフィルタリングを行うことができますRecursiveFilterIterator。たとえば、 にfinfo基づくアプローチ:

class MyRecursiveFilterIterator extends RecursiveFilterIterator
{
    private $finfo;

    function __construct(RecursiveIterator $i)
    {
        $this->finfo = new finfo(FILEINFO_MIME_TYPE);
        parent::__construct($i);
    }

    /**
     * Filter out files with a MIME type of image/*
     */
    public function accept()
    {
        $file = $this->current();
        $filetype = $this->finfo->file($file);

        $type_parts = explode("/", $filetype, 2);
        $type = $type_parts[0];

        return ("image" !== $type);
    }

}

$scan_it = new RecursiveDirectoryIterator(".");

foreach (new RecursiveIteratorIterator(
            new MyRecursiveFilterIterator($scan_it)) as $file)
{
    print ("$file\n");
}

同様にRecursiveRegexIterator、ファイル名ベースのアプローチを使用する場合にも使用できます。

于 2011-08-21T23:12:56.973 に答える
0

ファイルに関する情報を返すfinfo_file PHP 関数を使用できます。

このモジュールの関数は、ファイル内の特定の位置で特定のマジック バイト シーケンスを探すことによって、ファイルのコンテンツ タイプとエンコーディングを推測しようとします。これは防弾のアプローチではありませんが、使用されるヒューリスティックは非常にうまく機能します。

コード

<?php
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$scan_it = new RecursiveDirectoryIterator("/example_dir");

 foreach(new RecursiveIteratorIterator($scan_it) as $file) {
  echo finfo_file($finfo, $file) . "<br/>";
  }
finfo_close($finfo);
?>

出力は次のようになります。

image/png
directory
image/png
image/svg+xml

編集

したがって、次のような方法で非画像ファイルを取得できます。

if(!preg_match("/image.*/",finfo_file($finfo, $file)))
于 2011-08-21T22:26:27.130 に答える