min117の日記

初期desireもち。趣味Mac,メインFedora,仕事xp。

PHP 再帰関数その5(完成)

f:id:min117:20210102110716p:plain

 

PHP再帰関数によるフォルダ読み込み実装の続き。

min117.hatenablog.com

さらに改良。

 

今いるgetcwd()フォルダにあるオブジェクトを舐めて、フォルダだったらその中に入る(1階層降りる)+そこにあるオブジェクトをまた表示するためのボタンを再帰関数で実装した。

 

こういうフォルダだと

f:id:min117:20210102102112p:plain


こんな動きになる。

f:id:min117:20210102103242g:plain

これで、どんなに階層が深くてもフォルダを潜って辿れるシンプルなPHPができた。いろいろと活用できそう。

 

ソースはこれ。
f:id:min117:20210102110310p:plain

11行目 読み込む階層上限($kaisou_limit)は2とした。今いるフォルダの直下にあるディレクトリだけ取れればいいから。

19行目 $kaisou_limitはグローバル変数として宣言する。再帰で呼ばれた全ての関数インスタンスから参照されるから。

23〜56行目 読み込んだオブジェクトがファイルだった場合の処理

44〜46行目 ファイルの存在するPATHから文字列を切り出して、http://のリンクの一部として使う。explode()関数は、PATHをバラバラに切り離して配列に入れ、その一部だけを指定して利用できる。

57行目 ここに入るときは$pathには(ファイルじゃなくて)フォルダが入っていることが確定している。

 

f:id:min117:20210102110157p:plain

f:id:min117:20210102103620p:plain

フォルダの読み込みボタン実装が難しかった。

 

こんな感じで、フォルダの読み込みボタンが出る。

f:id:min117:20210102104527p:plain

 

86〜94行目でボタンを作って、submitでこのPHPファイルを読み込むと

f:id:min117:20210102104934p:plain

DIR_PATHがセットされるので

 

97行目の(if文の)処理に入るから

f:id:min117:20210102105135p:plain

 

そのif文中で実行してる再起関数つまりgetDirList()が発火して

f:id:min117:20210102105014p:plain

さらに下の階層を読みにいく。その際に、今いる階層を引数$kaisou_nowで渡す。

 

そうすると、再帰で呼ばれたgetDirList()関数インスタンスの中では、渡された階層に+1して表示してくれる。

f:id:min117:20210102105425p:plain

+1して、$kaisou_limitに達したら、何もしないで戻る。

 

コピペ+保存用

<?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>';

 

        //URLリンク表示

        $myFILE_PATH = $path;

        print '<br>================<br>';

        print $myFILE_PATH;

        print '<br>================<br>';

        // getDirList($path . '/' . $obj, $kaisou_now);

        // getDirList($myRUN1 . '/' . $obj, $kaisou_now);

 

        // explode()文字列分割 第三因数オプションにてlimit値(分割回数)を指定できる

        // /media/6TB/mp3z を スラッシュ区切りで3つに分割して配列に格納し

        //        6TB/mp3z ← その配列の2つ目(_STR[2])を表示する

        // localパス

        $myFILE_PATH_STR = explode("/", $myFILE_PATH ,3);

        print $myFILE_PATH_STR[2];

        print '<br>';

        // URL

 

        $myFILE_PATH_URL = 'http://192.168.3.11:8080/' . "$myFILE_PATH_STR[2]" ;

        print $myFILE_PATH_URL;

        print '<br>';

        print '<a href="' . "$myFILE_PATH_URL" . '" target="_blank">' . basename($myFILE_PATH) . '</a>';

        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>';

 

 

        ///// ボタンのクリックでphp関数を実行する

        // https://tutorialmore.com/questions-1286453.htm

        // print '<input type="button" name="someAction" value="Go" /><br>';

        // print '<form method="post">';

        print '<form method="GET">';

            print '<input type="hidden" name="DIR_PATH" id="ID_DIR_PATH" value="' . "$path" . '" /></br>';

            // print '<input type="submit" name="RUNNN2" id="ID_RUN2" value="RUN2" /></br>';

            print '<input type="submit" name="RUNNN2" id="ID_RUN2" value="' . basename($path) . '" /></br>';

        print '</form>';

 

        if($kaisou_now >= $kaisou_limit) {

            return 0;

        }

 

        // if(array_key_exists('RUNNN2',$_POST)) {

        if(array_key_exists('DIR_PATH',$_GET)) {

            $myDIR_PATH = $_GET['DIR_PATH'];

            print '<br>================<br>';

            print $myDIR_PATH;

            print '<br>================<br>';

            // getDirList($path . '/' . $obj, $kaisou_now);

            // getDirList($myRUN1 . '/' . $obj, $kaisou_now);

 

            // explode()文字列分割 第三因数オプションにてlimit値(分割回数)を指定できる

            // /media/6TB/mp3z を スラッシュ区切りで3つに分割して配列に格納し

            //        6TB/mp3z ← その配列の2つ目(_STR[2])を表示する

            // localパス

            $myDIR_PATH_STR = explode("/", $myDIR_PATH ,3);

            print $myDIR_PATH_STR[2];

            print '<br>';

            // URL

            $myDIR_PATH_URL = 'http://192.168.3.11:8080/' . "$myDIR_PATH_STR[2]" ;

            print $myDIR_PATH_URL;

            print '<br>';

            print '<a href="' . "$myDIR_PATH_URL" . '">' . basename($myDIR_PATH) . '</a>';

            print '<br>';

 

            // ディレクトリ内にあるオブジェクト(ファイルまたはディレクトリ)の一覧を入手

            // $obj_list = scandir($path);

            $obj_list = scandir($myDIR_PATH);

 

            foreach ($obj_list as $obj) {

                ///// ボタンのクリックでphp関数を実行する 

                // 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($myDIR_PATH . '/' . $obj, $kaisou_now);

 

                // print "$obj"; 

 

 

                // ディレクトリ内のオブジェクトを引数にして、自分自身を呼び出す再帰

                // 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);

 

 

 

?>

my_recursive07.php                                                     169,0-1       末尾

正月を利用して良いものつくれた。基礎的だけど根本的な部品って、こういう時間あるときしか作れない。かなり使い回しが効くはず。今年は良い年になりそうだ。