ディレクトリ内のすべてのファイルをループするPHPスクリプト?


131

ディレクトリ内のすべてのファイルをループして、フォーマット、印刷、リンクへの追加などのファイル名を使用できるPHPスクリプトを探しています。ファイルを名前、タイプ、または作成/追加/変更された日付でソートできるようにしたいと思います。(空想のディレクトリ「インデックス」を考えてください。)また、スクリプト自体やその他の「システム」ファイルなど、ファイルのリストに除外を追加できるようにしたいと考えています。(.および..「ディレクトリ」のように。)

スクリプトを変更できるようになりたいので、PHPのドキュメントを調べて、自分でスクリプトを作成する方法を学ぶことに興味があります。とはいえ、既存のスクリプト、チュートリアルなどがある場合は、お知らせください。


回答:


245

DirectoryIteratorを使用できます。PHPマニュアルの例:

<?php
$dir = new DirectoryIterator(dirname(__FILE__));
foreach ($dir as $fileinfo) {
    if (!$fileinfo->isDot()) {
        var_dump($fileinfo->getFilename());
    }
}
?>

3
注:多くのサーバーにはSPLがインストールされていないため、DirectoryIteratorクラスを使用できません(下の私の代替投稿を参照)。できればこれを使ってください!
NexusRex 2011

4
注[2]:dirname()上記の関数は、そこに配置したパスの親フォルダーを取得することを理解してください。私の場合、dirnameはディレクトリ名/パスのラッパーであると想定していたため、必要ありませんでした。
willdanceforfun 2016

また、dirnameが大きなファイルシステムである場合、メモリの問題が明白です。1ミリオンのファイルがある私の場合、アプリはmemory_limitに最大512MのRAMを必要とします。
abkrim

1
/home/examples/banana.jpg使用などの完全なパスが必要な場合$fileinfo->getPathname()
mgutt 2017年

!$ fileinfo-> isDir()を使用すると、ディレクトリに対するアクションを回避できます
LeChatNoir

44

DirectoryIteratorクラスにアクセスできない場合は、次のことを試してください。

<?php
$path = "/path/to/files";

if ($handle = opendir($path)) {
    while (false !== ($file = readdir($handle))) {
        if ('.' === $file) continue;
        if ('..' === $file) continue;

        // do something with the file
    }
    closedir($handle);
}
?>

4
あなたがそれにアクセスできない状況を挙げられますか?
Jochem Kuijpers

12
レガシーアプリケーションの多くはPHP 4を使用しており、DirectoryIteratorにアクセスできません。
Joseph Callaars 2014年

1
なぜ '。' === $ file?これはJavaではありません。
Dave Heq 2017

2
Dave ...いいえ、それはドットと一致し、PHPで一致しない場合は続行されません。==と===の違いを検索します。
JSG

22

scandir()関数を使用します。

<?php
    $directory = '/path/to/files';

    if (!is_dir($directory)) {
        exit('Invalid diretory path');
    }

    $files = array();
    foreach (scandir($directory) as $file) {
        if ($file !== '.' && $file !== '..') {
            $files[] = $file;
        }
    }

    var_dump($files);
?>

18

も利用できますFilesystemIterator。その場合、必要なコードはさらに少なくなりDirectoryIterator、およびは自動的に削除さ...ます。

// Let's traverse the images directory
$fileSystemIterator = new FilesystemIterator('images');

$entries = array();
foreach ($fileSystemIterator as $fileInfo){
    $entries[] = $fileInfo->getFilename();
}

var_dump($entries);

//OUTPUT
object(FilesystemIterator)[1]

array (size=14)
  0 => string 'aa[1].jpg' (length=9)
  1 => string 'Chrysanthemum.jpg' (length=17)
  2 => string 'Desert.jpg' (length=10)
  3 => string 'giphy_billclinton_sad.gif' (length=25)
  4 => string 'giphy_shut_your.gif' (length=19)
  5 => string 'Hydrangeas.jpg' (length=14)
  6 => string 'Jellyfish.jpg' (length=13)
  7 => string 'Koala.jpg' (length=9)
  8 => string 'Lighthouse.jpg' (length=14)
  9 => string 'Penguins.jpg' (length=12)
  10 => string 'pnggrad16rgb.png' (length=16)
  11 => string 'pnggrad16rgba.png' (length=17)
  12 => string 'pnggradHDrgba.png' (length=17)
  13 => string 'Tulips.jpg' (length=10)

リンク:http : //php.net/manual/en/class.filesystemiterator.php


5

このコードを使用して、ディレクトリを再帰的にループできます。

$path = "/home/myhome";
$rdi = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_PATHNAME);
foreach (new RecursiveIteratorIterator($rdi, RecursiveIteratorIterator::SELF_FIRST) as $file => $info) {
    echo $file."\n";
}

2

glob()には、ソートとパターンマッチングの機能があります。戻り値は配列であるため、必要な他のほとんどすべてのことを実行できます。


1
これは、大量のファイルを処理している場合を除き... 10,000以上です。メモリが不足します。
NexusRex 2011

@NexusRex:データベースから10,000レコードを読み取るべきではありませんが、質問に関する限り、これは範囲外です
bcosca

同意しました!ただし、データベースから読み取る場合は、「制限」を使用してページ番号を付けることができます。500万のXMLファイルが含まれるディレクトリを反復処理する場合は、このような運はありません。
NexusRex

SPL GlobIteratorがあります。
przemo_li 2017

2

完全を期すために(これはトラフィックの多いページのようです)、古き良きdir()関数を忘れないようにしましょう:

$entries = [];
$d = dir("/"); // dir to scan
while (false !== ($entry = $d->read())) { // mind the strict bool check!
    if ($entry[0] == '.') continue; // ignore anything starting with a dot
    $entries[] = $entry;
}
$d->close();
sort($entries); // or whatever desired

print_r($entries);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.