TOP > 読み物 > PHP: ぴゅーっと速くプログラミング > フレームワークを作ってみよう(6)

PHP: ぴゅーっと速くプログラミング

フレームワークを作ってみよう(6)

実践編1 足し算プログラムを作る

えー、本題の前に、前回のフレームワークにちょっと問題がありましたので修正しておきます。

framework.php: download source

  1: <?php
  2: /*
  3:  * framework.php
  4:  *   Copyright (C) YAMADA Satoshi
  5:  */
  6: 
  7: define('MYSELF',  $_SERVER['PHP_SELF']);
  8: 
  9: class
 10: framework
 11: {
 12:   function
 13:   framework()
 14:   {
 15:   }
 16: 
 17:   function
 18:   import($array)
 19:   {
 20:     $this->set($_GET, $array);
 21:     $this->set($_POST, $array);
 22:   }
 23: 
 24:   function
 25:   set($hash, $array)
 26:   {
 27:     $mq = ini_get('magic_quotes_gpc');        // 追加
 28:     foreach ($array as $name)
 29:       if (isset($hash[$name])) {        // この中変更
 30:         $this->$name      = $hash[$name];
 31:         $_name = "_$name";                // 念のため
 32:         $this->$_name     = htmlspecialchars(($mq)? stripslashes($this->$name):
 33:                                                     $this->$name);
 34:       }
 35:   }
 36: 
 37:   function
 38:   main()
 39:   {
 40:     $action = addSlashes($this->action);        // 追加
 41:     if (method_exists($this, $this->action)) $this->{$action}();
 42:     include "$action.html";
 43:   }
 44: }
 45: 
 46: // vi:ts=8 sw=2
 47: ?>

29行名のif文の中を前回変えたのですが、 $this->$name$hash[$name]を代入する時点で stripslashes()してしまってました。

$this->$nameは処理内部で使う変数ですので、 基本的には入力されたままの形で取扱います。 ということで表示用の$this->$_name(動かない環境があるようなので 一個変数を経由するようにしました)を設定するときにまとめて解毒処理するようにしました。


さて、本題。

今回からは一応実践ということで、実際の使用例を見ていきましょう。あ、実践と言ってもあまり実用的なものはまだ取り扱いませんので悪しからず。第一回は足し算CGIです。わざわざCGIでやる必要は全くないのですが、まずは簡単なところからということで。

で、実践編ではさらに趣向を凝らして、僕が今通ってる事務所の新人お二人に同じ課題で作ってもらうことにしました。今回はこんな感じで課題を出しました。

二つの数を足し算するプログラムを作りなさい。
用意する画面は入力画面と計算結果画面とし、
framework.php を使用すること(それ以外の実装は任意)。

それでは早速見ていきましょう。まずはKさん。

sample.php: download source

  1: <?php
  2: 
  3: require('framework.php');
  4: 
  5: class  sample extends framework {
  6:   function sample() {
  7:     $this->class_vars = array(
  8:                                 'action',
  9: 
 10:                                 'name',
 11:                                 'email',
 12:                               );
 13:     $this->import($this->class_vars);
 14: 
 15:     if (!$this->action) $this->action = 'form';
 16:   }
 17: }
 18: 
 19: $sample = new sample();
 20: $sample->main();
 21: 
 22: // vi:ts=8 sw=2
 23: ?>

form.html: download source

  1: <center>
  2: <h1>フォーム</h1>
  3: <form action="<?= MYSELF ?>" method="POST">
  4: <input type="hidden" name="action" value="done">
  5: 整数1: <input type="text" name="name" value="<?= $this->name ?>">
  6: <br>
  7: <h2>+</h2>
  8: 整数2: <input type="text" name="email" value="<?= $this->email ?>"><br>
  9: <input type="submit" value="答えへ">
 10: </form>
 11: </center>

done.html: download source

  1: <center>
  2: <h1>答え</h1>
  3: <h2><font color="blue">答えは?: <b><?= $this->name + $this->email?></font></h2>
  4: </center>

実行例はこちら

ふむ。 ちゃんと動いているようです。 プログラムにも特に問題はないですね。 さすが経験者。 変数名がこれまでのサンプルと同じなのはご本人も「手抜きです」とおっしゃってました。 仕事の合間にお願いします、ということだったのでこれは仕方ないですね。 まぁ手の抜き方もソツがないです。 ちゃんと押さえてるところは押さえてありますのでOKでしょう。 あと、強いて言えばdone.htmlの中で結果を計算しちゃってるところぐらいでしょうか。 まぁこれぐらいなら別に構わないとは思いますが、 できるだけプログラムコードはテンプレートの外に出す、という方針でしたので、 できればsampleクラスの中にdoneというメソッドを用意して、 そこで計算するようにすればもっとよかったかと思います。こんな感じですかね。

    :
class
sample extends framework
{
        :
    function
    done()
    {
        $this->answer = $this->x + $this->y;
    }
        :
}
    :

さてそれでは続いてO君のを見てみましょう。

sample.php: download source

  1: <?php
  2:   require('framework.php');
  3:   
  4:   class sample extends framework{
  5:     function sample(){
  6:       //$this->form_value = array('action','x','y','ans','ok','cancel',);
  7:       $this->form_value = array('action','x','cal','y','ans','ok','cancel',);
  8:       $this->import($this->form_value);
  9:       if(!$this->action){
 10:         $this->action = 'form';
 11:       }
 12:     }
 13:     
 14:     function form(){
 15:       $this->x = '足される数';
 16:       $this->y = '足す数';
 17:     }
 18:     
 19:     function check(){
 20:       if((!$this->x) || (!$this->y)){
 21:         $err[] = '値を入力してください';
 22:       }
 23:       if(preg_match("/[^0-9]/",$this->x) || preg_match("/[^0-9]/",$this->y)){
 24:         $err[] = '不正な値が入力されています';
 25:       }
 26:       if($err){
 27:         $this->error = '<ul><li>' . implode('<li>',$err) . '</ul>';
 28:         return 0;
 29:       }
 30:       return 1;
 31:     }
 32:     
 33:     function calclat($a,$b){
 34:       switch ($this->cal){
 35:         case '+':
 36:           $this->ans = $a + $b;
 37:           break;
 38:         case '-':
 39:           $this->ans = $a - $b;
 40:           break;
 41:         case '*':
 42:           $this->ans = $a * $b;
 43:           break;
 44:         case '/':
 45:           $this->ans = $a / $b;
 46:           break;
 47:       }
 48:     }
 49:     function done(){
 50:       if(!$this->check() || $this->cancel){
 51:         $this->action = 'form';
 52:         return;
 53:       }
 54:       $this->calclat($this->x,$this->y);
 55:       //$this->ans = $this->x + $this->y;
 56:     }
 57:     
 58:   }
 59:   
 60:   $sample = new sample();
 61:   $sample->main();
 62: ?>

form.html: download source

  1: <h1>算数</h1>
  2: 
  3: <?php if($this->error); ?>
  4: <p><b><font color="red"><?=$this->error ?></font></b></p>
  5: <?php endf ?>
  6: 
  7: <form action="<?= MYSELF ?>" method="POST">
  8: <input type="hidden" name="action" value="done">
  9: <input type="text" name="x" value="<?= $this->_x ?>">
 10: <select name="cal">
 11: <option value="+">+
 12: <option value="-">-
 13: <option value="*">×
 14: <option value="/">÷
 15: <input type="text" name="y" value="<?= $this->_y ?>"><br>
 16: <input type="submit" name="ok" value="答え">
 17: <input type="submit" name="cancel" value="リセット">
 18: </form>

done.html: download source

  1: <h1>結果</h1>
  2: 
  3: <form action="<?= MYSELF ?>" method="POST">
  4: <input type="hidden" name="action" value="form">
  5: <b>答え</b><br>
  6: <b><?= $this->x ?><?= $this->cal ?><?= $this->y ?>=<?= $this->ans ?></b><br>
  7: <input type="submit" name="ok" value="戻る">
  8: </form>

実行例はこちら

これは素晴らしいですね。 「足し算CGIを作れ」という課題にも関わらず、四則演算できるようにまでしてくれてます。 しかもちゃんとpreg_match()を使って入力チェックまで。 実はO君は、PHPはこれが初めてなんですよ。 びっくりです。 強いて言えばform.html<select>タグのところ。 もうちょっと工夫できる余地がありそうですよね。 ここのところは今後解説する予定です。

さてそれではもう見る必要もないかと思いますが一応解答例を。

addition.php: download source

  1: <?php
  2: 
  3: require('framework.php');
  4: 
  5: class
  6: Addition extends framework
  7: {
  8:   function
  9:   Addition()
 10:   {
 11:     $this->class_vars = array(
 12:       'action',
 13: 
 14:       'x',
 15:       'y',
 16:     );
 17:     $this->import($this->class_vars);
 18: 
 19:     if (!$this->action) $this->action = 'form';
 20:   }
 21: 
 22:   function
 23:   form()
 24:   {
 25:   }
 26: 
 27:   function
 28:   check()
 29:   {
 30:     if (!$this->x) {
 31:       $err[] = 'Xを入力してください';
 32:     }
 33:     if (!$this->y) {
 34:       $err[] = 'Yを入力してください';
 35:     }
 36:     if ($err) {
 37:       $this->error = '<ul><li>'. implode('<li>', $err). '</ul>';
 38:       return 0;
 39:     }
 40:     return 1;
 41:   }
 42: 
 43:   function
 44:   done()
 45:   {
 46:     if (!$this->check() || $this->cancel) {
 47:       $this->action = 'form';
 48:       return;
 49:     }
 50: 
 51:     $this->answer = $this->x + $this->y;
 52:   }
 53: }
 54: 
 55: $addition = new Addition();
 56: $addition->main();
 57: 
 58: // vi:ts=8 sw=2
 59: ?>

form.html: download source

  1: <h1>足し算</h1>
  2: 
  3: <?php if ($this->error): ?>
  4: <p><strong><font color="red"><?= $this->error ?></font></strong></p>
  5: <?php endif ?>
  6: 
  7: <form action="<?= MYSELF ?>" method="POST">
  8: <input type="hidden" name="action" value="done" />
  9: X
 10: <input type="text" name="x" value="<?= $this->_x ?>" />
 11: +
 12: Y
 13: <input type="text" name="y" value="<?= $this->_y ?>" />
 14: =
 15: <input type="submit" value="計算" />
 16: </form>

done.html: download source

  1: <h1>足し算結果</h1>
  2: 
  3: <p>
  4: <strong><?= $this->_x ?></strong>
  5: +
  6: <strong><?= $this->_y ?></strong>
  7: =
  8: <strong><?= $this->answer ?></strong>
  9: <br >
 10: です。
 11: </p>
 12: 
 13: <form action="<?= MYSELF ?>" method="POST">
 14: <input type="hidden" name="action" value="form" />
 15: <input type="hidden" name="x" value="<?= $this->_x ?>" />
 16: <input type="hidden" name="y" value="<?= $this->_y ?>" />
 17: <input type="submit" value="もう一度" />
 18: </form>

実行例はこちらです。

次回はもうちょびっとだけステップアップした課題にチャレンジする予定です。


[ 前へ | 次へ ]