忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2024/04/16 17:37 |
PHP1-8:KWICを作ってみる

KWICを作ってみるの続きです。

あちらでフロント部分を作成したので、今回はバックエンド部分の作成です。

整形は面倒ですが、プログラム的には特に難しいことを行っているわけではありません。
innerHTMLがGET形式で送られてくるので、それを受け取ってテキストを作成して返す、それだけです。
返すといっても、行うことはブラウザに表示するのと全く同じです。
ブラウザからのリクエストの場合、表示した文はブラウザの画面上に表示されますが、XMLHttpRequestからのリクエストへの返答はresponseTextの中に入ります。

'gingatetsudono_yoru.txt'は、青空文庫から拾ってきてください。

このプログラムの場合、読み込むファイル名をHTML側で決めているので、簡単に詐称が可能です。
隠しておきたいサーバ内のファイルを読み出されたりしかねませんので、サーバ側で必ず引数のチェックを行ってください。
以下の例の場合は拡張子がtxtかどうかというだけの緩い制限になっていますが、本来は許可するファイルのリストを作り、それ以外であれば不許可にすべきです。
特に、以下のコードそのままだとディレクトリトラバーサルの格好の餌食となります。
それ以前に、HTMLにファイル名を出さなくていい方法もありますので、実用する際はできるだけセキュリティ的に安全な方法を選びましょう。

inclemental_server.php

<?php
      #==========================================================
      #初期設定
            #----------------------------------------------------------
            #検索元ファイルの取得
            $file_name=$_GET['title'];
            #----------------------------------------------------------
            #検索文字列引数の受け取り
            $search_word=$_GET['query'];
            #----------------------------------------------------------
            #返却用変数の初期化
            $xxxxx="";
            #----------------------------------------------------------
            #セキュリティ対策ルーチン
            $sub_security=sub_security();
            if($sub_security!=""){
                        print(mb_convert_encoding($sub_security,"UTF-8","EUC-JP"));
                        exit;
            }

      #==========================================================
      #メインルーチン
            #----------------------------------------------------------
            #検索元ファイルを取得
            $file_contents=@file_get_contents($file_name);
            #----------------------------------------------------------
            #無ければ終了
            if(!$file_contents){print(mb_convert_encoding("ファイルが存在しません","UTF-8","EUC-JP"));exit;}
            #----------------------------------------------------------
            #検索処理
            //検索用に改行を削除
            $file_contents=str_replace("\r","",$file_contents);
            $file_contents=str_replace("\n","",$file_contents);
            //検索ルーチン実行
            $search_result=sub_search($search_word,$file_contents);
            //おまじない
            $search_result=mb_convert_encoding($search_result,"UTF-8","UTF-8");
            //表示、inclemental2.jsに返却
            print_r($search_result);
            //終了
            exit;

      #==========================================================
      #検索を実行するサブルーチン
      function sub_search($search_word,$file_content){
            #----------------------------------------------------------
            #初期設定
            //文字列検索位置初期化
            $str_position=0;
            //最大ループ回数
            $countmax=30;
            //前後何文字を取得するか
            $print_string=50;
            #----------------------------------------------------------
            #検索処理
            for($countx=0;$countx<$countmax;$countx++){
                  //検索文字の位置
                  $str_position=strpos($file_content,$search_word,$str_position+1);
                  //終わってれば終了
                  if(!$str_position){break;}
                  //前のほうの文字取得
                  if($str_position<$print_string){
                        $search_result_pre=substr($file_content,0,$str_position);
                  }else{
                        $search_result_pre=substr($file_content,${str_position}-$print_string,$print_string);
                  }
                  //後のほうの文字取得
                  $search_result_post=substr($file_content,${str_position}+strlen($search_word),$print_string);
                  //検索文字列の文字取得
                  $search_result_mid='<span class="search_result">'.$search_word.'</span>';
                  //文字列の作成
                  $search_result.=$search_result_pre.$search_result_mid.$search_result_post.'<br />';
            }
            //返却
            return $search_result;
      }

      #==========================================================
      #セキュリティ対策のサブルーチン
      function sub_security(){
            #----------------------------------------------------------
            #エラーメッセージ
            $error_message="";
            #----------------------------------------------------------
            #検索ファイルは.txtに限定
            if(substr($_GET['title'],-3,3)!="txt"){
                  $error_message.=("要求しているファイルが不正です".substr($file_name,-3,3));
            }
      return $error_message;
      }
?>


一見面倒ですが、やっていることはテキストからHTML文を作成しているだけです。

XMLHttpRequestはUTF-8しか受け付けません。
そのために表示文字列の文字コードをUTF-8にする必要があるのですが、PHPファイルがEUC-JP、テキストファイルとjsはUTF-8、そしてHTMLファイルはSJISで書かれているという不健康極まりない状態です。
テキストファイルのUTF-8データと、PHPで付け足したEUC-JPのデータを、一見無用な文字コード変換を入れることで無理矢理統一しています。
まあ揃えられるなら全部揃えたほうが安全です。

さあ、これでリロードを伴わない動的な検索サービスを作成することができました。
http://yuubiseiharukana.creativeroot.jp/js2/2-5-1.html


さて、今回は直接HTMLタグまで書き込んだ上で返信を行っていますが、これはMVCの観点からあまり正しい方法とは言えません。
データの送受信はJSONで行い、jsとcssで装飾を行ったほうがレイアウト変更等にも対処しやすく便利です。
が、個人的にJavaScriptでのパースが苦手なのでPHPで行っています。

XML?
企業同士ならともかく、個人ユースでXMLは資源の無駄としか言い様が。

PR


2008/06/23 15:14 | Comments(0) | TrackBack() | PHP

トラックバック

トラックバックURL:

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<JSP1-2:JSPで暗黙オブジェクト | HOME | その他1-4:セキュリティ対策4:クロスサイトリクエストフォージェリ>>
忍者ブログ[PR]