ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

ゼロからはじめるPHP講座コミュのWEBサイト自動構成CGIの作成 - ディレクトリ情報の再帰的な取得と処理

  • mixiチェック
  • このエントリーをはてなブックマークに追加
私は現在、WEBサイトを自動的に構成するCGIを
作成しようとしております。
私自身WEBサイト管理とPHPの勉強の為に
作成しておりますが
色々と問題点があると思いますので
その部分についてのアドバイスを頂ければ、と思いトピックを作成しました。
以下は予定している機能です。

(1)更新時に.htmlファイルを作成、公開する。
アクセスのたびにCGIを作動させるより省エネ。

(2)サイト構造(ディレクトリ構造)を前もって定義しておいて、一括で構成可能。

(3)テンプレート機能
一度デザインすればあとは内容を書き換えたりするだけで
小説とか、同じデザインで内容だけ違う場合に有効。

(4)リンク更新機能
ファイル、ディレクトリを移動、名前変更した時に同時にリンクも更新する機能

今回は(2)に関わってくる処理です。
次のトピックスで更に具体的な処理を用意しておきます。

<!-- タブのインデントは表示を保つ為に タブ1つを半角スペース「 」4つに置換してあります -->

<?php
/*
ディレクトリ階層の情報を再帰的に処理する部分については
いわしたゆうじ氏(http://www.sound-uz.jp/php/tips/index.html
から許可を頂いた上で掲載しております。

公開、配布したい場合は連絡下さい。
copyright (c) vis All Rights Reserved
*/

/*
サイトの定義情報と実際のサイトのディレクトリツリーの情報を管理するクラス
ディレクトリを表す場合末尾に”/”を加え、ディレクトリの終端は”../”で表す。
定義情報をファイルから読み込んだ際に事前に"\t"や"\n"等を取り除いてからこのクラスに処理させる。
*/

class site_info_control {
//エラー情報を保持する配列。
//書式は、関数名、エラーメッセージ、引数
    var $err_buff = array();
//ディレクトリの情報を再帰的に取得し、1次元配列として返す。
//ディレクトリを表す場合末尾に”/”を加え、ディレクトリの終端は”../”で表す
    function getdirtree( $dir )
    {
        if( !is_dir( $dir ) ){ // ディレクトリでなければ false を返す
            array_push($this->err_buff, "func : getdirtree \nerr : is not dir\narg : ".$dir."\n\n");
            return false;
        }
    
        $tree = array(); // 戻り値用の配列
    
        if( $handle = opendir( $dir ) )
        {
            while ( false !== $file = readdir( $handle ) )
            {
                // 自分自身と上位階層のディレクトリを除外
                if( $file != "." && $file != ".." )
                {
                    if( is_dir( $dir.$file."/" ) ){
                        array_push($tree, $file."/");
                        // ディレクトリならば再帰呼出
                        $tmp_array = $this->getdirtree( $dir.$file."/" );
                        array_splice($tree, count($tree), count($tmp_array), $tmp_array);
                        //ディレクトリの終端を表すためにディレクトリの終端に"../"を追加する。
                        array_push($tree, "../");
                    }else{
                        // ファイルならばパスを格納
                        array_push($tree, $file);
                    }
                }
            }
            closedir( $handle );
            //ksort($tree);
        }
        return $tree;
    }

//サイトのディレクトリ情報を比較しやすい形式に変換する。
//配列キーにパスを用いる事で比較が容易になる。配列の値はフラグ。
    function set_key_value($array){
        if(!is_array($array)){
            array_push($this->err_buff, "func : set_key_value \nerr : is not array\narg : ".$array."\n");
            return false;
        }
        $formed_array = array();
        //パスを得るためのスタック
        $path = array();
        foreach($array as $key => $value){
            if($value == "../"){
                //ディレクトリの終端に達したので、そのディレクトリ名を捨てる
                array_pop($path);
            }else{
                //スタックからパスを作成する
                $cwd = join("", $path);
                if(ereg( "[a-zA-Z0-9_]+/$", $value) ){
                    //ディレクトリを認識したのでそのディレクトリ名をスタック積む
                    array_push($path, $value);
                }
                //比較の為にフラグを立てておく
                $formed_array[$cwd.$value] = true;
            }
        }
        return $formed_array;
    }

//定義情報とサイトのディレクトリ情報を比較、不一致要素を配列として返す。
//連想配列のキーの値を使って比較する。
//array_cmp(実在情報, 定義情報)
    function array_cmp($array_tree, $array_define){
        if( !is_array( $array_tree ) || !is_array( $array_define ) ){
            array_push($this->err_buff, "func : array_cmp \nerr : is not array\narg : ".$array_tree." & ".$array_define."\n");
            return false;
        }
        //戻り値用配列
        $array = array();
        //実在するファイル情報を元に定義したファイル情報と比較する
        foreach($array_tree as $key => $value ){
            if( true == $array_define[ $key ] ){
                //ファイルが合致した場合、定義情報の値を負にしておく
                $array_define[ $key ] = false;
            }else{
                //実在するファイル、ディレクトリの不一致
                $array[ $key ] = "real unmach";
            }
        }
        //定義したファイル情報で、値が正のものが不一致ファイルとなる
        foreach($array_define as $key => $value){
            if( true == $value ){
                //定義したファイル、ディレクトリの不一致
                $array[$key] = "virtual unmach";
            }
        }
        return $array;
    }

//ディレクトリ情報ファイルを出力用に変換
    function output_struct($array){
        if(!is_array($array)){
            array_push($this->err_buff, "func : output_struct \nerr : is not array\narg : ".$array."\n");
            return false;
        }
        //戻り値用配列
        $formed_array = array();
        //インデント用
        static $indent_count = 0;
        
        foreach($array as $value){
            //ディレクトリの終端判断
            if($value == "../"){
                $indent_count--;
                $indent = ( $indent_count ) ? str_repeat( "    ", $indent_count ) : "";
                array_push($formed_array, $indent."../");
            }else{
                $indent = ( $indent_count ) ? str_repeat( "    ", $indent_count ) : "";
                //ディレクトリ、ファイルの判別
                if(ereg( "[a-zA-Z0-9_]+/$", $value) ){
                    $indent_count++;
                }
                array_push($formed_array, $indent.$value);
            }
        }
        return $formed_array;
    }
}

//以下テスト用
echo "<pre>\n";
$tree = new site_info_control;
$dirinfo = $tree->getdirtree("./");
//echo "\"".join("\", \"", $dirinfo)."\"\n";
//比較用の定義情報
$defineinfo = array("dir1/","file1","dir2/","../","dir3/","file2","dir4/","file3","../","../","../");
$dirinfo = $tree->output_struct( $dirinfo );
print_r( $dirinfo );

$dirinfo = $tree->getdirtree("./");
$dirinfo = $tree->set_key_value( $dirinfo ); //比較の為に変換
$defineinfo = $tree->set_key_value( $defineinfo ); //比較の為に変換
$cmpinfo = $tree->array_cmp( $dirinfo, $defineinfo );
print_r( $cmpinfo );
echo "</pre>";
?>

コメント(4)

申し訳ないのですが、
改善点を見つけたのでこのトピックはこれから一日以内に
削除しようと思います。
教えてください、だけでなく、解決したらしたで情報を共有するのがコミュだと思うのですが…
管理人さんにお任せします。
すみません、私なりに煮詰めて載せたのですが、
詰めが甘かったようなので、
一度頭を冷やす意味でトピックを削除しようと思っておりました。

削除する必要が無いのでしたらお言葉に甘えさせていただこうと思います。
管理人です。
プログラムって、見るたびに「あー」とか思って、書き方とかいまいち良くなかったり、小さいところでバグが出たりするものですから、visさんも気にしなくていいと思います。

このトピックは、visさんの意思に任せますね。
解決したソースを上げてもらうと、みんなのためになると思います。しかし、できればでいいです。特に無理強いはしません。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

ゼロからはじめるPHP講座 更新情報

ゼロからはじめるPHP講座のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング