第 4 講オブジェクト指向プログラミングを体験しよう! 第 3 講で体験したのは 1 input_text.php で フォームからデータを入力して送信 2 file_writer.php で 受信したデータを整形してテキストファイルに保存 3 file_reader.php で テキストファイルからデータを読み込んで表示というものでした その際 保存には 1) テキストファイルを開く 2) ファイルに書き込む 3) ファイルを閉じるという作業が 読込表示には 1) テキストファイルを開く 2) ファイルから読み込む 3) ファイルを閉じるという作業が必要でした ということは 今後 テキストファイルとの間でデータのやり取りをする場合 その都度 これらの処理のためのコードを記述しなければならないということになりそうです これらは いわば お決まりの処理 です にもかかわらず その都度 同じようプログラムとして記述しなければならないというのは 面倒かつ無駄な気がします もし これらの お決まりの処理 をどこかにまとめておいて 必要な時に呼び出して使えるなら file_writer.php は 保存のためのデータの整形だけに力を注げますし file_reader.php では 読み込んできたデータの表示に注力することができます 本講で体験する オブジェクト指向プログラミング (Object Oriented Programming) では こうしたお決まりの処理は クラス と呼ばれるプログラムとして作成しておいて 必要に応じて呼び出して使うことができます つまり よく行う定型的な処理 ( 業務ロジック といいます) は 部品 化しておいて使いまわそうという発想です そこで オブジェクト指向プログラミングとは何か を概観した上で ファイル入出力専用クラスの作成と利用 を体験しておきましょう
司令塔プログラムオブジェクト指向プログラミング (Object Oriented Programming) とは 私たちが普通に ソフトウェア といっているのは 売上管理とか会計処理といった目的を達成するための1つのシステムです オブジェクト指向プログラミングでは このシステムを 司令塔プログラム ( 全体の流れをコントロールする側 ) と 部品プログラム ( 司令塔からの命令で実際に働く側 ) に分けて作り上げていく手法を採ります 部品プログラム B 部品プログラム A 部品プログラム C この部品に該当するのが オブジェクト (Object) です 問題は 何を部品 =Object にするかです プログラミングは しばしば 現実世界の事象をコンピュータ上で再現すること と定義されます この定義を前提にすると オブジェクトとは コンピュータ上で再現したい事象に登場する " モノ " であり それが部品化の対象となります ここでいう " モノ " とは 必ずしも形のある物 ( 有体物 ) とは限りません 目には見えないけれども 私たちが頭で観念することができるものであれば データベースとのやり取り 仕訳 評価 といった仕組みや制度でも " モノ " と考えることができます 本講の冒頭で述べた テキストファイルとのやり取り ( の仕組み ) も 目には見えませんが オブジェクト ( 部品 ) となりうるわけです
オブジェクト指向プログラミングの オブジェクト指向 とは プログラミングのモデルとなる現実世界の事象に登場するモノ =Object の再現を目指す といった意味だと考えてよいと思います もともと Object とは 対象 とか モノ のことであり Oriented( オリエンティド ) とは ~を目指した という意味です オブジェクト指向プログラミングを実践するためには 現実世界の事象をモデルにして そこにはどんな モノ が登場するのか そのモノはどんなデータを持ち どんな働きをすればいいのか また 複数のモノが登場するのなら モノ同士の関係はどうなっているのかの分析が欠かせません ( これを モデリング といいます ) そして 分析結果から 再現目的を達成するのに必要な範囲で モノ とそのモノが持つ データ と 機能 を洗練し それをその モノ にふさわしい名前をつけた クラス としてひとまとめにします 人間プレイヤー名前武器 ( グー チョキ パー ) 勝点名前を答える () 出す手を決める () 決めた手を出す () 勝点を加算する () 勝点を答える () クラスの候補 データ 機能 ジャンケンゲームにおける 人間プレイヤー のモデリング結果 最後に オブジェクト指向に対応するプログラミング言語のルールにしたがって これをそのままコードとして記述すれば プログラムとしての クラス の出来上がりです あとは 全体の流れをコントロールする司令塔プログラムから呼び出して使うだけです 司令塔プログラムでは 1 部品クラスの実体を生成し 2その実体が持つ機能 ( メソッド ) を呼び出すという方法で利用します 部品化されたクラスは 実体を作り出すための設計図 ( 雛形 ) であり その雛形をもとに生成される実体の方を オブジェクト と言うのが一般です そこで 混乱を避けるために 実体の方は インスタンス と呼んで クラスと区別するのが通例です
ファイル入出力専用クラスを作る では 実際に Forget-Me-Not システムで使える ファイル入出力専用クラス を作ってみましょう なお このクラスのデータと機能は下図のものとします ( クラス候補図 ) ( クラス図 ) ファイル入出力 FileIO パス ファイルへの経路 $path ファイル名 パス + ファイル名 $dirfile ファイルハンドル ファイルオブジェクト名 $handle ファイルをオープンする () open( $mode ); ファイルをロックする () lock( $lock ); ファイルに書き込む () write( $line ); ファイルから読み込む () read(); ファイルを閉じる () close(); [1] FileIO クラスを作成する 新規にメモ帳を開いて 以下のコードを入力します class FileIO { // フィールド ( 共通データ ) private $path; // private( プライベート ) は private $dirfile; // 他のクラスからアクセスできない private $handle; // ことを意味する修飾子 // コンストラクタ ( このクラスの実体を生成するための特殊なメソッド ) function construct( $path, $fname ) { $this->path = $path; フィールドへのアクセスに $this->dirfile = $path.$fname; は $this-> フィールド名 という方法をとる
// ファイルをオープンするメソッド function open( $mode ){ if(!file_exists( $this->path ) ) { // 指定パスが存在しない場合には mkdir( $this->path ); // 必要なディレクトリを作成する $this->handle = fopen( $this->dirfile, $mode ); // ファイルをロックするメソッド function lock( $lock ){ flock( $this->handle, $lock ); メソッドの ( ) 内の変数は 引数 といい このメソッドの処理には指定のデータが必要であることを宣言するもの // ファイルに書き込むメソッド function write( $line ) { $flag = false; if( fputs( $this->handle, $line ) ) return $flag; $flag = true; // ファイルから読み込んで値を返すメソッド function read() { $content = ""; while(!feof( $this->handle ) ) { $content.= fgets( $this->handle); return $content; return $content の部分は このメソッドの処理結果を呼び出し元に返す宣言 // ファイルを閉じるメソッド function close() { $flag = false; if( fclose( $this->handle ) ) return $flag; // クラス終わり $flag = true;
[2] FileIO クラスを保存する 以下の要領でファイルを保存します < 手順 > 1.notebook フォルダを丸ごとコピーして [oop_notebook] とする 2. ファイルを保存する 保存先 : oop_notebook ファイル名 : FileIO.class.php ファイルの種類 : すべて文字コード : UTF-8 [3] file_writer.php を変更する oop_notebook フォルダ内の file_writer.php を修正します < 手順 > 1.file_writer.php をメモ帳で開く 2. 中身を次のように変更する require_once ( 'FileIO.class.php' ); // FileIO クラスの読込み $line = date( 'Y 年 m 月 d 日 H:i:s' )." t"; // 書き込みデータの設定 $line.= $_POST['subject']." t"; // データの受け取り $line.= $_POST['topic']." t"; // データの受け取り $line.= $_POST['comment']." t"; // データの受け取り $fio = new FileIO( "./data/", "note.txt" ); // インスタンス ( 実体 ) 生成 $fio->open( 'ab' ); $fio->lock( LOCK_EX ); $fio->write( $line ); $fio->close(); // 後処理 : リダイレクトのためにヘッダ情報を出力 header( 'Location: http://localhost/oop_notebook/input_text.php' ); 3. 修正後 上書き保存する
[4] システムを実行する 以下のように URL アクセスする < 手順 > 1.xammp-control.exe を実行 2.Apache を start する 3. ブラウザを起動する 4. 以下の URL にアクセスする http://localhost/oop_notebook/input_text.php 5. データを入力する科目 : プログラミングⅠ 項目 : オブジェクト指向コメント : 現実世界の事象に登場するモノを部品として再現することを目指すこと 6.[ 送信 ] する エラー表示なく 最初の画面に戻れば OK [oop_notebook] フォルダ内に [data] フォルダが作られ その中に note.txt ファイルがあれば成功です データをもう一件入れておきましょう ネタは何でも OK です 次ページで行う修正による結果を確認するのに必要です
[5] file_reader.php を修正する file_reader.php を開いて 次のように変更し 上書き保存します require_once '../Encode.php';?> <html> <title> プログラミングⅠ:Forget-Me-Not</title></head> <body> <h1>read from Text</h1> require_once ( 'FileIO.class.php' ); // FileIO クラスの読込み $fio = new FileIO( "./data/", "note.txt" ); // インスタンス ( 実体 ) 生成 $fio->open( 'rb' ); $fio->lock( LOCK_SH ); $data = $fio->read(); $row = explode( " n", $data ); $i=0; while($i<count($row)-1){ $buf = explode( " t", $row[$i] );?> <ul> <li> print( $buf[1] );?></li> <li> print( $buf[2] );?> </li> <li> print( $buf[3] );?></li> <li> print( $buf[0] );?></li> </ul> <hr color="#ffaa66" /> $i++; $fio->close(); // ファイルを閉じる?> 上書き保存後は ブラウザから実行し </body> 結果を確認しましょう </html>