zz log

zaininnari Blog

無名関数(クロージャー)でファイル一覧取得

環境

  • PHP Version 5.3.0

■参考

[PHP] 無名関数への変数の引継ぎ
http://idocsq.net/page/95

無名関数(クロージャー)でファイル一覧取得

<?php
/**
 *
 * 指定されたパスのファイルとディレクトリのリストを取得する
 *
 * @param string  $filePath 絶対パス or 相対パス
 * @param string  $pattern  正規表現パターン。nullで無効。
 *                          ターゲットは、ファイル名($subject = 'index.php')
 * @return array  ファイルパスを収容した一次配列
 */

$f = function($filePath,$pattern = null) use (&$f) {
	$result = array();
	if(!is_dir($filePath)) return $result;
	$filePath = realpath($filePath);
	foreach (scandir($filePath) as $file) {
		if ($file === '.' || $file === '..') continue;
		if (
			is_file($filePath . DIRECTORY_SEPARATOR .$file) &&
			($pattern === null || preg_match($pattern, $file))
		) {
			$result[] = $filePath . DIRECTORY_SEPARATOR . $file;
			continue;
		}
		$next = $filePath . DIRECTORY_SEPARATOR . $file;
		$result = array_merge($result,$f($next,$pattern));
	}
	return $result;
};
?>

使い方

<?php
//絶対パスを指定。フィルターなし
$fileList = $f('/var/www/html/');//-> array('/var/www/html/index.php','/var/www/html/css/style.css')

//[/var/www/html/index.php]
//相対パスを指定。フィルターパターンなし -> 返り値は、絶対パスに変換される。
$fileList = $f('./');//-> array('/var/www/html/index.php','/var/www/html/css/style.css')

//絶対パスを指定。フィルターパターンあり。
$fileList = $f('/var/www/html/','/php$/');//-> array('/var/www/html/index.php')

//空のフォルダを指定 -> 空の配列を返す
$fileList = $f('/var/www/html/js');//-> array()

//マッチしないフィルターパターンを指定 -> 空の配列を返す
$fileList = $f('/var/www/html/','/cgi$/');//-> array()

//存在しないパスを指定 -> 空の配列を返す
$fileList = $f('/var/www/html/admin');//-> array()

//不正なフィルターパターン
$fileList = $f('/var/www/html/','][');//-> preg_match()のWarningエラー
?>

TIPS

  • 比較演算子「==」より「===」のほうが速い
  • 自作関数のネスト > create_function > 無名関数の順で速い
  • 論理演算子「||」を使うとき、判定を先にしたい方を左へ

例外ver

<?php
try {
    if (
        is_file($filePath . DIRECTORY_SEPARATOR .$file) &&
        ($pattern === null || preg_match($pattern, $file))
       ) {
            $result[] = $filePath . DIRECTORY_SEPARATOR . $file;
            continue;
        }
} catch (InvalidArgumentException $e) {
    return;
}
?>
広告を非表示にする