とても人当たりが良いと評判ですが、気を許すと周囲のことを見下しがちな、ユゲタです。
よくないですね〜。
そんな僕は、どんなに疲れていても、常に見上げる姿勢になれるジャイアント馬場(故)さんの信念を尊敬しています。
人のことを信用することを信条にしていて、「裏切るより裏切られるほうがいいじゃないか」という名言が個人的にすごくお気に入りです。
そういや、最近作り直しているPHPフレームワークで、ファイル検索をする際に使うscandir機能で、毎回拡張子判定を行ったり、システムファイル(除外対象)を判別する処理がめんどくさいな〜と思っていた時、
もしかしたらscandorのオプションをあまり知らずに、やっぱりソート機能しかなかったのですが、他の機能と組み合わせることで、かなり簡易な記述ができることがわかりました・・・orz
scandirの使い方
これまで使っていた書き方は次のような感じで、検索したフォルダのパスを入れていて、その結果をfor分内で処理するだけでした。
// filesフォルダの中身を表示
$files = scandir("files/");
for($i=0; $i$lt;count($files); $i++){
if($files[$i] === "." || $files[$i] === ".."){continue;}
echo $files[$i].PHP_EOL;
}
> array
> (
> [0] .
> [1] ..
> [2] a.txt
> [3] b.txt
> [4] c.txt
> )
phpのマニュアルサイトには、オプション機能として、第2引数にsortのON/OFFフラグがあると書いてあっただけなので、とりあえず実行テスト。
// sort
$files_0 = scandir("../../",0);
$files_1 = scandir("../../",1);
// 昇順
print_r($files_0);
> array
> (
> [0] .
> [1] ..
> [2] a.txt
> [3] b.txt
> [4] c.txt
> )
// 降順
print_r($files_1);
> array
> (
> [0] c.txt
> [1] b.txt
> [2] a.txt
> [3] ..
> [4] .
> )
そして、不要なシステムファイルを除外する場合の書き方
// システムファイルの除外
$files = array_diff(scandir("files/"),array('..','.'));
print_r($files);
> Array
> (
> [2] => a.txt
> [3] => b.txt
> [4] => c.txt
> )
ちょっと連想配列とkey値が気になるので、下記のように配列に変換
// システムファイルの除外
$files = array_values(array_diff(scandir("files/"),array('..','.')));
print_r($files);
> Array
> (
> [0] => a.txt
> [1] => b.txt
> [2] => c.txt
> )
さらに、単一階層だけでなく、複数の階層にも対応している関数は以下のように書けます。
<?php
function dirToArray($dir) {
$result = array();
$cdir = scandir($dir);
foreach ($cdir as $key => $value)
{
if (!in_array($value,array(".","..")))
{
if (is_dir($dir . DIRECTORY_SEPARATOR . $value))
{
$result[$value] = dirToArray($dir . DIRECTORY_SEPARATOR . $value);
}
else
{
$result[] = $value;
}
}
}
return $result;
}
$files = dirToArray("dirs/");
print_r($files);
> Array
> (
> [a] => Array
> (
> [0] => a.txt
> )
>
> [b] => Array
> (
> [0] => b.txt
> )
>
> [c] => Array
> (
> [0] => c.txt
> )
>
> )
不要なシステムファイル判定などやらなくてもよくなる、任意の拡張子のみ抽出するスニペット
<?php
$all = array_diff(scandir("docs/") , array("..","."));
print_r($all);
function scanFiles($path="",$exts=array()){
if(!$path || !is_dir($path)){return array();}
$files = array_diff(scandir($path) , array("..","."));
// 拡張子指定無し
if(!$exts){
return $files;
}
// 拡張子指定有り
$arr = array();
$names = array();
foreach($files as $file){
$pathinfo = pathinfo($file);
if(!in_array($pathinfo["extension"] , $exts)){continue;}
$arr[] = $pathinfo;
}
return $arr;
}
print_r(scanFiles("docs",["html","md"]));
> Array
> (
> [2] => README.md
> [3] => common.css
> [4] => index.html
> [5] => main.js
> )
> Array
> (
> [0] => Array
> (
> [dirname] => .
> [basename] => README.md
> [extension] => md
> [filename] => README
> )
>
> [1] => Array
> (
> [dirname] => .
> [basename] => index.html
> [extension] => html
> [filename] => index
> )
>
> )
pathinfoの情報がピンポイントで便利そうだったので、こんな感じにしてみました。
return値のdirnameには、$pathを入れたほうがいいですね。
これにさらに、ファイル名の文字列検索機能や、多重階層対応にすると、非常に強力な検索ツールになりそうです。
簡単なスニペットを目指したつもりが、まあまあな関数になっちゃいましたね。
見下しすぎました・・・
0 件のコメント:
コメントを投稿