連載
» 2007年07月31日 00時00分 公開

今から始める MySQL入門(9):「オンラインストア」完成へ向けて各ファイルを再構築 (1/4)

[鶴長鎮一,@IT]

 連載第8回の「外部キー制約を活用する」では、DTO・DAOパターンを使って作成した「簡易在庫管理システム」を「簡易オンラインストア」に統合する前提として、外部制約キーについて説明しました。外部制約キーを利用することにより、複数のテーブルにまたがる値を関連付けることができます。

 今回は、第5回「MySQLの基礎を学ぼう [サンプル開発編]」で作成した「簡易オンラインストア」をDTO・DAOパターンで再構築し、簡易在庫管理システムと統合していきます。これでオンライストアの大まかな処理を完成させます。

関連リンク:

連載 快速MySQLでデータベースアプリ!

http://www.atmarkit.co.jp/flinux/index/indexfiles/mysqlindex.html

連載 今から始める MySQL入門

http://www.atmarkit.co.jp/flinux/index/indexfiles/mysql5index.html


サンプルファイルの展開

 今回もサンプルアーカイブ「sample5.tgz」を利用します。ダウンロードは下記から可能です。インストール手順については前回の説明を参照してください。

サンプルダウンロード:

sample5のtarアーカイブ


 sample5.tgzを展開すると、インストールされるファイルは以下のようになります。

sample5のファイル構成

sample5
#DAOクラス
┣━ BaseDao.php
┣━ CountDao.php
┣━ ItemDao.php
┣━ Order_mainDao.php

#DTOクラス
┣━ Count.php
┣━ Item.php
┣━ Order_item.php
┣━ Order_main.php

#簡易オンラインストア
┣━ menu.php
┣━ confirm.php
┣━ purchase.php
┣━ icon.jpg

#簡易在庫管理システム
┣━ displayStock.php
┣━ updateStock.php

#データベース「sample_db5」のダンプファイル
┗━ sample_db5.sql


共通する処理を基底クラスに集約

 今回は、使用するMySQLのテーブルが増えたことに、DAOクラスも多くなっています。それぞれのDAOクラスについて、MySQLサーバへの接続手順や切断手順を個別に記述するのは非効率です。

 これを効率化する方法が、MySQL関連の共通する処理を「基底クラス」に集約することです。各DAOクラスは基底クラスを継承し、基底クラスのメソッドや値を使用できるようにします。

 例えば基底クラス「BaseDao.php」では、コンストラクタ/デストラクタ/MySQLサーバ接続手順/MySQLサーバ切断手順が定義されています。この基底クラスを継承したサブクラス「CountDao.php」でも、これらの手順を利用することができます。

 基底クラスを継承するには、CountDao.phpの2行目のように、クラス名の宣言に続けて「extends BaseDao」を付加します。BaseDao.phpのMySQLに関連するメソッドや値にはprotected修飾子を設け、メソッドや値の使用をそのクラスとサブクラスに限定します(注)

注:「public/private/修飾子なし」については、第6回「DAOパターンですっきりコーディング!」を参照してください。


基底クラスの実例

 では、基底クラスの使い方を見るために、BaseDao.phpとCountDao.phpのソースコードをのぞいてみましょう。

 1  <?php
 2  class BaseDao{
 3
 4    protected $mysqli = null;
 5
 6    //コンストラクタ
 7    function __construct(){
 8      $this->connect();
 9    }
10
11    //デストラクタ
12    function __destruct(){
13      $this->disconnect();
14    }
15
16    //MySQLサーバへ接続
17    protected function connect(){
18      if(is_null($this->mysqli)){
19        $this->mysqli = new mysqli("localhost", "php", "password",
 "sample_db5");
20        $this->mysqli->query("SET NAMES utf8");
21        if(mysqli_connect_errno()){
22          die("MySQLサーバ接続に失敗しました <br>理由:" . mysqli_connect_error());
23        }
24      }
25    }
26
27    //MySQLサーバと切断
28    protected function disconnect(){
29      is_null($this->mysqli) or $this->mysqli->close();
30    }
31  }
32  ?>
      リスト1 BaseDao.php

 1  <?php
 2  class CountDao extends BaseDao{
 3
 4    //コンストラクタ
 5    function __construct(){
 6      parent::__construct();
 7    }
 8
 9    //デストラクタ
10    function __destruct(){
11      parent::__destruct();
12    }
13
14    //max_noの現在値を取得し、max_noをインクリメント
15    public function currVal(){
16      is_null($this->mysqli) and $this->connect();
17      $count = new Count();
18      $this->mysqli->autocommit(FALSE);
19      $result = $this->mysqli->query("SELECT max_no FROM count FOR UPDATE");
20      $row = $result->fetch_array(MYSQLI_NUM);
21      if( !$this->mysqli->query("UPDATE count SET max_no = max_no + 1;") ){
22        die("登録に失敗しました(1001) " . $this->mysqli->error . "\n");
23      }
24
25      $count->setMax_no($row[0]);
26      $this->mysqli->commit();
27      $result->close();
28      return $count;
29    }
30  }
31  ?>
      リスト2 CountDao.php

 ただし、継承にも例外があります。コンストラクタ/デストラクタはサブクラスに継承されません。そのため、サブクラスでコンストラクタ/デストラクタを利用する場合は、あらためて定義する必要があります。

 サブクラスのCountDao.phpでは、親クラス(BaseDao.php)のコンストラクタを呼び出すように「parent::__construct();」を使用しています。デストラクタでも同様に、「parent::__destruct();」で親クラスのデストラクタを利用するよう記述しています。

 なお、SQLクエリの中で特別な意味を持つ文字列のエスケープ処理については、前回までは各処理の中で行っていました。今回は、それを各DAOの中で行うように修正を加えています。DAOの中では「mysqli->real_escape_string()」メソッドを使用し、よりMySQLサーバに則した特殊文字のエスケープを実施しています。

       1|2|3|4 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。