フォルダ階層の再帰関数による読み込み。前回の続き。
改良して、以下の機能を実装した。
・読み込んだオブジェクトが
ファイルの場合は何もしないけど
フォルダの場合には「Go」ボタンを表示して、押せばさらに下の階層に行けるようにした(というか、そうしたいので、まずはGoボタンだけ表示した)
・現在いる場所(getcwd)の階層($kaisou_now)を関数の引数として受け取るようにした。
子フォルダを読み終えて親フォルダに戻る時に階層を1減らすとこの実装が難しいんだけど、子フォルダを読む(再帰する)ときに、今の階層($kaisou_now)を引数で渡せば解決することが分かった。そうすれば、子フォルダに行くときだけ階層が+1されて、戻った時には前の階層数に戻ることができる。
・読み込む階層の深さ($kaisou_limit)を指定できるようにした。
あらかじめ階層の深さ限界($kaisou_limit)を宣言しておいて
$kaisou_nowがそれより深く潜る前にreturn する。
$kaisou_limit をユーザーに入力させれば、読み込みたい任意の深さまでのフォルダを辿るようにできる。$kaisou_limitは(再帰された関数インスタンスの)全てから参照されるので、グローバル変数としておく(19行目)。
ソース変更による動きの変化はこんな感じ。
次回はさらに改良して「Go」ボタン押下でそのフォルダ階層に降りていく処理を実装する。Goボタン(input type="button"のとこ。下のソースの58行目)を押した時に再起関数を呼ぶとこの実装が難しそう。
今回のソース全景。
コピペ保存用
<?php
// nikkei XTECK
// 54. 再帰関数を使ってみよう
// https://xtech.nikkei.com/it/article/COLUMN/20070827/280408/
// 引数$path にはディレクトリorファイルの絶対パスを指定する。
// $saiki = 0;
$kaisou_now = 0;
$kaisou_limit = 2;
function getDirList($path ,$kaisou_now) {
/// 階層を引数で受け取ると、親フォルダに戻った時に正しく階層-1される
/// global $kaisou;しちゃうと、親フォルダに戻った時に階層+1されバグる
// global $saiki;
// global $kaisou_now;
// $total_size = 0;
global $kaisou_limit;
print '<br>';
//指定したのがファイルだった場合はサイズを返して終了
if (is_file($path)) {
// print '再帰:' . $saiki . '回目';
// print '<br>';
print '<font color="blue">ファイル</font>パス:<br>' . "$path";
print '<br>';
print '階層:' . $kaisou_now;
print '<br>';
return filesize($path);
} elseif (is_dir($path)) {
// カレントディレクトリ(.)or
// 上位階層ディレクトリ(..)の場合はここで終了
$basename = basename($path);
if ($basename == '.' || $basename == '..') {
return 0;
}
// if ($kaisou_now == 3) {
// return 1;
// }
// ファイルでもなく、カレント(.)でもなく、親(..)でもない
// つまりディレクトリだったら、フォルダpathとして表示
print '<font color="red">フォルダ</font>パス:<br>' . "$path";
print '<br>';
// 階層を表示
$kaisou_now++;
print '階層:' . $kaisou_now;
print '<br>';
print '階層limit:' . $kaisou_limit;
print '<br>';
print "$obj";
print '<input type="button" name="someAction" value="Go" /><br>';
if($kaisou_now >= $kaisou_limit) {
return 0;
}
// ディレクトリ内にあるオブジェクト(ファイルまたはディレクトリ)の一覧を入>手。
$obj_list = scandir($path);
foreach ($obj_list as $obj) {
///// ボタンのクリックでphp関数を実行する
// https://tutorialmore.com/questions-1286453.htm
// print '<input type="button" name="' . basename($obj) . '" id="id_' . basename($obj) . '" value="RUN" onclick="' . getDirList($path . '/' . $obj) . '" /><br>';
///// ↓ これだと、onclick()と書いても、クリックの有無に関係なくgetDirListが読まれてしまう
// サーバがパースしちゃうから
// print '<input type="button" name="test" id="test" value="RUN" onclick="' . getDirList($path . '/' . $obj) . '"/><br>';
// if( is_dir($obj)) {
// }
getDirList($path . '/' . $obj, $kaisou_now);
// ディレクトリ内のオブジェクトを引数にして、自分自身を呼び出す再帰
// getDirList($path . '/' . $obj);
// $total_size += getDirList($path . '/' . $obj);
// $objがディレクトリだったら
// また自分自身を呼び出す(再帰)して…を繰り返して
// 最深部の階層(ファイルのみが存在する階層)まで行く
}
// return $total_size;
// print '階層ぅ:' . "$kaisou_now" . '<br>';
} else {
return 0;
}
}
// カレントフォルダの確認
print '------------------------<br>';
print getcwd() . '<br>';
print '階層:' . $kaisou_now;
print '<br>';
print '------------------------<br>';
//関数実行
// print getDirList('/media/WD30EZRX/PT3/test_pdf2jpg');
// print getDirList("getcwd()");
// print getDirList("/media/6TB/mp3z");
print getDirList(getcwd(), 0);