[PHP]多階層ディレクトリ内のファイル一覧を取得する

Facebook にシェア
Delicious にシェア
LINEで送る
Pocket

ディレクトリ内にあるファイル一覧を表示するには scandir() や DirectoryIterator クラスを使えばできますが、ディレクトリ内にさらにサブディレクトリが有る場合は再帰的に処理するための工夫が必要です。
方法は2つあり、RecursiveIteratorIterator() と RecursiveDirectoryIterator() を組み合わせる方法と、再帰関数を利用した従来の方法です。


RecursiveIteratorIterator() と RecursiveDirectoryIterator() を使った方法

<?php
//検索するディレクトリ
$dir = dirname(__FILE__) . '/directory/';

$result = list_files($dir);
print_r($result);

function list_files($dir){
	$iterator = new RecursiveIteratorIterator(
		new RecursiveDirectoryIterator(
			$dir,
			FilesystemIterator::SKIP_DOTS
	  		|FilesystemIterator::KEY_AS_PATHNAME
			|FilesystemIterator::CURRENT_AS_FILEINFO
		), RecursiveIteratorIterator::LEAVES_ONLY
	);

	$list = array();
	foreach($iterator as $pathname => $info){
		$list[] = $pathname;
	}
	return $list;
}

FilesystemIterator::SKIP_DOTS は「.」「..」をスキップします。
FilesystemIterator::CURRENT_AS_FILEINFO を指定すると current() として SplFileInfo クラスの形で得られるので、より詳細なファイルの情報も合わせて取得できます。
FilesystemIterator::KEY_AS_PATHNAME を指定すると key() としてファイルパス+ファイル名が得られます。

「RecursiveIteratorIterator::LEAVES_ONLY」を指定すると「葉のみ」、つまりファイルのみが取得されます。
ディレクトリ名も含めて取得するには「RecursiveIteratorIterator::SELF_FIRST」か「RecursiveIteratorIterator::CHILD_FIRST」を指定します。
この2つの違いはディレクトリから先に取得するかファイルから先に取得するかの違いです。

foreach() でリストに追加する際、キー部分を利用していますが $info->getPathname() としても同じ内容が得られます。


再帰関数を使った方法

scandir() で取得したリストから is_file() と is_dir() を用いてファイルかディレクトリかの区別を行い、必要に応じて再帰関数を実行します。

<?php
//検索するフォルダ
$dir = dirname(__FILE__) . '/twism-master/';

$result = list_files($dir);
print_r($result);

function list_files($dir){
	$list = array();
	$files = scandir($dir);
	foreach($files as $file){
		if($file == '.' || $file == '..'){
			continue;
		} else if (is_file($dir . $file)){
			$list[] = $dir . $file;
		} else if( is_dir($dir . $file) ) {
			//$list[] = $dir;
			$list = array_merge($list, list_files($dir . $file . DIRECTORY_SEPARATOR));
		}
	}
	return $list;
}

取得したファイル名には「.」「..」などが含まれるためその場合はスキップします。
対象がファイルであればリストに追加し、ディレクトリであればその内容を再帰的に取得します。
フォルダ自体も一覧に含めるのであれば「$list[] = $dir;」のコメントアウトを外します。


実行結果(実行環境によって異なります)

Array
(
    [0] => /home/user/www/sample/directory/1.txt
    [1] => /home/user/www/sample/directory/2.txt
    [2] => /home/user/www/sample/directory/level1/3.txt
    [3] => /home/user/www/sample/directory/level1/dir1/4.txt
    [4] => /home/user/www/sample/directory/level1/dir1/5.txt
    [5] => /home/user/www/sample/directory/level1/dir2/6.txt
    [6] => /home/user/www/sample/directory/level1/dir2/7.txt
)

例は Linux サーバー上での実行例です。
フォルダ内の7つのファイルすべてが絶対パスで取得されています。
なお、scandir() は PHP5 以上で使用できます。
PHP4 で実行する場合は opendir() などで代用する必要があります。
また、「allow_url_fopen」などの設定が有効になっていない場合はリモートファイル(他のサーバーのファイル)の一覧を取得することはできません。


Similar Posts:




  • This entry was posted in PHP and tagged . Bookmark the permalink.

    One Response to [PHP]多階層ディレクトリ内のファイル一覧を取得する

    1. Pingback: [PHP]ディレクトリー(フォルダ)の階層を維持したまま圧縮する | PHP Archive

    コメントを残す

    メールアドレスが公開されることはありません。