では、データベース操作を一まとめにしたItemDaoクラスを見てみましょう。
1 <?php
2 class ItemDao{
3
4 private $mysqli = null;
5
6 //コンストラクタ
7 function __construct(){
8 $this->connect();
9 }
10
11 //デストラクタ
12 function __destruct(){
13 $this->disconnect();
14 }
15
16 //MySQLサーバへ接続
17 private function connect(){
18 if(is_null($this->mysqli)){
19 $this->mysqli = new mysqli("localhost", "php",
"password", "sample_db2");
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 private function disconnect(){
29 is_null($this->mysqli) or $this->mysqli->close();
30 }
31
32
33 //全アイテムの取得
34 public function getAllItem(){
35 is_null($this->mysqli) and $this->connect();
36 $result = $this->mysqli->query("SELECT * FROM item");
37 $item_array = array();
38
39 while($row = $result->fetch_array(MYSQLI_ASSOC)){
##<--MYSQLI_NUMではなく
40 $item = new Item();
41 $item->setId($row["id"]);
42 $item->setName($row["name"]);
43 $item->setDetail($row["detail"]);
44 $item->setPrice($row["price"]);
45 $item->setQty($row["qty"]);
46 $item_array[] = $item;
47 }
48 $result->close();
49 return $item_array;
50 }
51
52 //指定されたアイテムの取得
53 private function getItem($sql){
54 is_null($this->mysqli) and $this->connect();
55 $result = $this->mysqli->query($sql);
56
57 $item = null;
58
59 if($result->num_rows != 0){
60 $row = $result->fetch_array(MYSQLI_ASSOC);
61 $item = new Item();
62 $item->setId($row["id"]);
63 $item->setName($row["name"]);
64 $item->setDetail($row["detail"]);
65 $item->setPrice($row["price"]);
66 $item->setQty($row["qty"]);
67 }
68 $result->close();
69
70 return $item;
71 }
72
73 //idでアイテムを取得
74 public function getItemById($id){
75 $sql = "SELECT * FROM item WHERE id = '$id'";
76 return $this->getItem($sql);
77 }
78
79 //nameでアイテムを取得
80 public function getItemByName($name){
81 $sql = "SELECT * FROM item WHERE name = '$name'";
82 return $this->getItem($sql);
83 }
84
85 //アイテムの更新
86 public function updateItem($item){
87 is_null($this->mysqli) and $this->connect();
88 $sql = "UPDATE item SET
89 name = '" . $item->getName() . "',
90 detail = '" . $item->getDetail() . "',
91 price = '" . $item->getPrice() . "',
92 qty ='" . $item->getQty() . "'
93 WHERE id = '" . $item->getId() . "'";
94 if( !$this->mysqli->query($sql)){
95 print "登録に失敗しました(1001) " . $this->mysqli->error
. "\n";
96 }
97 }
98
99 //新規アイテムの登録
100 public function insertItem($item){
101 is_null($this->mysqli) and $this->connect();
102 $sql = "INSERT INTO item values ('', #idカラムに空を挿入
することで、auto_incrementによるカウントアップ値を代入できる
103 '" . $item->getName() . "',
104 '" . $item->getDetail() . "',
105 '" . $item->getPrice() . "',
106 '" . $item->getQty() . "')";
107 if( !$this->mysqli->query($sql)){
108 print "登録に失敗しました(1002) " . $this->mysqli->error
. "\n";
109 }
110 }
111
112 //指定されたアイテムの削除
113 public function deleteItem($item){
114 $this->deleteItemById($item->getId());
115 }
116
117 //idで指定されたアイテムの削除
118 public function deleteItemById($id){
119 is_null($this->mysqli) and $this->connect();
120
121 $sql = "DELETE FROM item WHERE id = '" . $id . "'";
122 if( !$this->mysqli->query($sql)){
123 print "削除に失敗しました(1003) " . $this->mysqli->error
. "\n";
124 }
125 }
126
127 }
128 ?> |
リスト5 ItemDao.php
外部から参照不可なpublicメソッド、内部からのみ参照可能なprivateメソッドについては先ほど紹介しました。なお、内部から内部のメソッドや変数を呼び出す場合は「$this->」を使用します。
以下、ItemDaoクラス内部からのみ参照可能なメソッド(private)です。
- connect()
MySQLサーバに接続し、mysqliインスタンスを生成。主に__construct()メソッドから実行される
- disconnect()
MySQLサーバと接続されているか(mysqliインスタンスが生成されているか)どうかを確認し、接続されていれば切断。主に__destruct()メソッドから実行される
- getItem(文字列)
SQLクエリーを引数に該当する商品アイテムをitemテーブルから検索し、結果をItem型で引き渡す。getItemById()、getItemByName()メソッドは引き渡された商品idや商品名をSQLクエリーに変換し、ItemDaoクラス内でgetItem()を実行
注:MySQLサーバの接続手順、挿入、抽出などの手続きは第5回を参考のこと。
基本的な操作は、第5回で紹介したとおりです。ただし、今回はデータの引き渡しにItemクラスを使用しています。MySQLサーバからデータを抽出した後、Itemクラスのセッターメソッドを使って変数をセット(40〜46行目、61〜66行目)し、Itemクラスを受け取ったクラスはゲッターメソッドを使って各変数を取得します。
なお、第5回でMySQLサーバからデータを抽出する際、「fetch_array(MYSQLI_NUM)」を使用し、「$row[0]、$row[1]……」のように数字を添え字にカラムデータを取得しました。しかし、今回のItemDao.php(リスト5)では「fetch_array(MYSQLI_ASSOC)」を使用し(39、60行目)、「$row["id"]、$row["name"]……」のようにカラム名で値を取得しています。
itemテーブルから該当データを検索するgetItem()メソッドは、SQLクエリーを引数に取りますが、直接外部から使用されることはありません。getItemById()やgetItemByName()メソッドを通してのみ実行されます。
54行目の「is_null()」では、mysqliインスタンスの有無を確認します。mysqliがnullならMySQLサーバと接続されていないと判断して、connect()メソッドで接続を行います。
検索結果が1件以上あれば(59行目)、Itemクラスにitemテーブルから抽出した値をセットします(61〜66行目)。なお、getItem()では指定されたSQLに対し、2件以上該当があっても最初の1件のみが引き渡されます。
updateItem()、insertItem()、deleteItem()は、Itemクラスを引数に取ります。Itemクラスから各変数を取り出して処理を行います。更新や削除では、該当データを何らかの手段で特定する必要がありますが、商品idが不変なため、idをWHERE句の条件に指定し処理を行っています。それぞれのメソッドはSQLクエリーを作成、実行します。結果があれば受け取り、Item型にして戻しています。
検索以外の「挿入」「更新」「削除」の実行例は、それぞれsample4ソースファイルの「sample4-2.php〜sample4-4.php」で確認できます(下記、参照)。実行は、コマンドラインphpで行います。
14 $item_dao->insertItem($item); |
挿入、insertItem()メソッドの実行「sample4-2.php」
15 $item_dao->updateItem($item); |
更新、updateItem()メソッドの実行「sample4-3.php」
11 $item_dao->deleteItem($item); |
削除、deleteItem()メソッドの実行「sample4-4.php」
# pwd
/..pathto../sample4/CommandLine
# php -f ./sample4-2.php ←sample4-2.phpの場合
(ソースからインストールした場合には/usr/local/bin/php) |
なお、itemテーブルから全商品アイテムを検索するgetAllItem()メソッドでは、Itemクラスを複数戻す必要があるため、配列arrayを利用しています。ItemDao.php(リスト5)の37〜49行目のようにすれば、配列arrayにItem型を格納することができます。
$sample_array = array();
$sample_array[] = "文字列1";
$sample_array[] = "文字列2";
$sample_array[] = "文字列3";
(省略) |
配列arrayの利用(各要素の格納例)
また、取り出す際は、sampe4.phpの10〜15行目のような処理を行います。getAllItem()メソッドの使用例は、以下のとおりです。
foreach($sample_array as $sample){
print $sample;
} |
配列arrayの利用(全要素の引き出し例)
次回は、今回解説したItemクラスやItemDaoクラスを実際に「在庫管理システム」に組み込み、在庫管理システム本体の処理がいかに簡素化されるかを確認してみましょう。 (次回に続く)