PHPでディレクトリ内のファイル一覧を取得する方法

PHPでディレクトリ内のファイル一覧を取得する方法

PHPを使って、指定したディレクトリ内にある、全てのファイル名やファイルパスを取得する方法を説明します。まとめて処理をしたい場合などに便利です。

サンプルコード

特定のディレクトリを指定して、ファイル名と、ファイルのパスを出力するサンプルコードです。ディレクトリは無視します。

PHP

<?php
	// ディレクトリのパスを記述
	$dir = "/var/www/syncer/" ;

	// ディレクトリの存在を確認し、ハンドルを取得
	if( is_dir( $dir ) && $handle = opendir( $dir ) ) {
		// [ul]タグ
		echo "<ul>" ;

		// ループ処理
		while( ($file = readdir($handle)) !== false ) {
			// ファイルのみ取得
			if( filetype( $path = $dir . $file ) == "file" ) {
				/********************

				  各ファイルへの処理

				  $file ファイル名
				  $path ファイルのパス

				********************/

				// [li]タグ
				echo "<li>" ;

				// ファイル名を出力する
				echo $file ;

				// ファイルのパスを出力する
				echo " (" . $path . ")" ;

				// [li]タグ
				echo "</li>" ;
			}
		}

		// [ul]タグ
		echo "</ul>" ;
	}

取得のイメージ

先ほど、紹介したサンプルコードのプログラムで、下記構成の、syncerディレクトリを指定してみます。

syncer

  • var
    • www
      • syncer
        • 1.txt
        • 2.php
        • 3.html
        • 4.js
        • 5.css
        • syncer-sub
          • 6.txt

次のように、ディレクトリ(syncer-sub)以下は無視されて、ファイルの情報のみを取得することができます。

  • 5.css (/var/www/syncer/5.css)
  • 2.php (/var/www/syncer/2.php)
  • 3.html (/var/www/syncer/3.html)
  • 4.js (/var/www/syncer/4.js)
  • 1.txt (/var/www/syncer/1.txt)

プログラミング

一覧を取得するのに肝となる関数が、opendir()readdir()という2つの関数です。

opendir()

opendir()にディレクトリへのパスを指定すると、そのディレクトリへの「ハンドル」を返してくれます。これは言葉では表現しにくいのですが…、拙いのですが、ディレクトリに繋いだ「パイプ」のようなものをイメージして下さい。このパイプを通って、情報が流れてくるようなイメージです。

PHP

<?php
	// ディレクトリへのパス
	$dir = "/var/www/syncer/" ;

	// ハンドルを取得
	$handle = opendir( $dir ) ;

readdir()

readdir()の引数にハンドルを指定すると、そのディレクトリ内にある「エントリ」を1つ返してくれます。「エントリ」とは、ファイルやディレクトリのことです。例えば、下記のsyncerディレクトリのハンドル($handle)があったとします。

syncer

  • var
    • www
      • syncer
        • 1.txt
        • 2.php
        • 3.html
        • 4.js
        • 5.css
        • syncer-sub
          • 6.txt

readdir()$handleを指定して実行すると、1.txtを取得することができます。

PHP

// エントリを1つ取得
$entry1 = readdir( $handle ) ;

// [$entry1]の中身
// [1.txt]

続けて、2回目、3回目とreaddir()を実行すると、2個目、3個目…とエントリを取得することができます。このように、ファイル、ディレクトリを取得していくことができます。先ほどのサンプルデモでは、「エントリがディレクトリの場合は無視する」という命令を別途、加えてました。エントリの順番は、名前順や更新順ではありません。「サーバーのシステムに格納されている順番」です。任意の順番にしたい場合は、別途、ソート処理を施す必要があります。

PHP

// エントリを1つ取得 (2回目)
$entry2 = readdir( $handle ) ;

// [$entry2]の中身
// [2.php]

// エントリを1つ取得 (3回目)
$entry3 = readdir( $handle ) ;

// [$entry3]の中身
// [3.html]

そして、もうエントリが存在しない7回目には何が取得できるか?それは、Boolean値のfalseです。このfalseを停止条件にしてwhile()でループ処理をすることで、「ディレクトリの中のファイル一覧を取得する」が実現するというわけです。

PHP

// エントリを1つ取得 (7回目)
$entry7 = readdir( $handle ) ;

// [$entry7]の中身
// false

応用編

ファイル一覧を取得して、まとめて処理できる便利なことをまとめてみました。色々と工夫してみて下さいね。

ファイルをまとめて消す

unlink()を使って、ディレクトリ内の全てのファイルを削除することができます。

PHP

<?php
	// ディレクトリのパスを記述
	$dir = "/var/www/syncer/" ;

	// ディレクトリの存在を確認し、ハンドルを取得
	if( is_dir( $dir ) && $handle = opendir( $dir ) ) {
		// ループ処理
		while( ($file = readdir($handle)) !== false ) {
			// ファイルのみ取得
			if( filetype( $path = $dir . $file ) == "file" ) {
				// 各ファイルへの処理
				unlink( $path ) ;
			}
		}
	}

ファイルをまとめて読み込む

独自のCMSなどを制作時、ライブラリファイルがたくさんある場合、それらのPHPファイルを特定のディレクトリ内に集めて設置しておき、まとめてrequireで読み込むと、お手軽です。いちいちファイル名を指定する必要がありません。

PHP

<?php
	// ディレクトリのパスを記述
	$dir = "/var/www/syncer/" ;

	// ディレクトリの存在を確認し、ハンドルを取得
	if( is_dir( $dir ) && $handle = opendir( $dir ) ) {
		// ループ処理
		while( ($file = readdir($handle)) !== false ) {
			// ファイルのみ取得
			if( filetype( $path = $dir . $file ) == "file" ) {
				// 各ファイルへの処理
				require $path ;
			}
		}
	}

古いファイルにのみ処理をする

「古いファイルだけを削除したい」などという場合に、時間を指定して、更新がそれよりも過去のファイルのみに、処理を適用することができます。ディレクトリのパスを間違えると、意図しないファイルを削除してしまう危険があるので、くれぐれもご注意下さい。

PHP

<?php
	// 時間 (今から7日前)
	$time = strtotime( "-7 day" ) ;

	// ディレクトリのパスを記述
	$dir = "/var/www/syncer/" ;

	// ディレクトリの存在を確認し、ハンドルを取得
	if( is_dir( $dir ) && $handle = opendir( $dir ) ) {
		// ループ処理
		while( ($file = readdir($handle)) !== false ) {
			// ファイルのみ取得
			if( filetype( $path = $dir . $file ) == "file" ) {
				// 各ファイルへの処理
				if( $time > filemtime($path) ) {
					// 古いファイルにだけ適用する処理
					// unlink( $path ) ;
				}
			}
		}
	}