データベース接続の共通化とCRUDシステムの完成


Webアプリケーションシステムを制作する際にはデータベースと関係するページが多く,データベースの接続と終了を行う処理を何回も実行する必要があります。

これを全てのPHPスクリプトに書き込むのは効率が悪い上に見通しも悪くなります。それを避けるため,データベース接続用の処理を一つのPHPスクリプトにまとめ,データベースを使う前に各PHPスクリプトからrequire('接続処理用PHPスクリプト名')を実行するようにします。

こうすることで,データベースの接続処理を共通化することができ,MySQL環境が変わっても,この接続処理用PHPスクリプトだけを変更すれば,これを読み込むすべてのPHPスクリプトのデータベース接続処理を変更したことになる訳です。

データベース接続用PHPスクリプトの作成と共有

まず初めに下のようなデータベース接続用PHPスクリプトdbconnect.phpを作成します。この時,HTMLの部分は不要なので注意してください

PHPスクリプト:dbconnect.php

例として,このdbconnect.phpを使ってデータベースを利用するプログラムを作成してみましょう。下記のPHPスクリプトは,前の節で作ったSELECT命令を使ったテーブル全表示スクリプトを改良したものです。

データベース接続文の代わりに

require('dbconnect.php');
と書き,データベース接続用スクリプトをこの部分に読み込んで使用しています。なお上記のカッコは省略可能です。

PHPスクリプト: select.php

実行結果

ここまで出来たら,同様にして前回作成したinsert.php, delete.php, update.phpも,データベース接続処理部分をrequire('dbconnect.php');に置き換えて動作確認をして下さい。

CRUDシステムを構築する

データベースを使ったWebアプリとして,次の4つの機能を備えたものをCRUD(クラッド)システムと呼びます。

ユーザからは,PHPの後ろに存在するデータベースは意識させず,フォームを通じてだけ,データの入出力ができるようにするのが標準的なWebのCRUDシステムです。用途ごとにUI(ユーザーインターフェース)は柔軟に変える必要がありますが,ここでは今まで作ってきたPHPスクリプトを改良する形で最小限のCRUD Webアプリを作っていくことにします。

では最初に,htdocsフォルダにminicrudフォルダを作り,そこに今まで作ってきたPHPスクリプト(select.php, insert.php, delete.php, update.php, dbconnect.php)一式をコピーしておきます。以降はこのコピーしたファイルに手を加えていきます。

次に,minicrudフォルダにindex.htmlを作り,同じフォルダにあるselect.phpへのリンクを追加します。

index.htmlの例

ここで,select.phpには次の機能を追加しておきます。

  1. size, memoフィールドのデータも表示する
  2. index.htmlへ戻るリンクを付加し,ユーザを迷子にしないように配慮

改良したselect.phpの表示例

フォームからデータを入力する(insert.php)

次はinsert.phpに次のようなフォームを付け,追加するデータをフォームから入力し,データベースに保存できるよう改良します。idは自動的に付加させたいので,あらかじめphpMyAdminからAuto incrementの設定を追加しておいて下さい。

改良したinsert.phpの表示例

しかし,フォームに入力された内容をそのまま信用してはいけません。なぜならユーザーが誤って情報を入力してしまったり,「SQLインジェクション(injection)」という攻撃にさらされることがあるからです。

このような情報は「サニタイズ(sanitize)=無害化」という作業を行う必要があります。 PHPでSQL文をサニタイズする場合使用するファンクションがmysqli_real_escape_stringです。フォームのデータは,なるべく以前使ったhtmlspecialcharsで無害化した上で,mysqli_real_escape_string関数を噛ませたものだけをデータベースに入力させるようにしましょう。

PHPスクリプト: insert.phpを改良

入力サンプル

↓↓
実行結果

実行したら,データがきちんと挿入できたかどうか,select.phpで確認して下さい。

[注意] 上記のように2重サニタイズを行うと,データベースに書き込んだUTF-8の文字列が文字化けして読めなくなります。実行には支障ありませんが,気になるようならどちらかのサニタイズ処理を取りやめて下さい。

サニタイズ処理をまとめる(dbconnect.phpの改良とinsert.phpの再改良)

2段階にわたるサニタイズ処理が面倒なので,まとめて実行する関数sanitizeを作り,dbconnect.phpに追加します。

PHPスクリプト: dbconnect.phpを改良

これによって,insert.phpの処理が簡略化できます。定義したsanitize関数を使ってPHPスクリプト部分を書き換えてみましょう。

PHPスクリプト: insert.phpを再改良

PHPスクリプトがだいぶん短くなりました。これを使って,「ハチ」「10」「昆虫」を追記してみましょう。改良前と同じように動作して,データが次のようになっていればO.K.です。

実行結果

完成したら,index.phpにinsert.phpへのリンクを追加しておいて下さい。

既存データを削除する(select_delete.php作成とdelete.phpの改良)

既存データを削除するためには,まずどのデータを削除したいのか,一覧表からユーザに選んでもらう必要があります。そのために,select.phpをselect_delete.phpにコピーし,各データの先頭に「削除」ボタンを付けることにします。

select_delete.php完成イメージ

「削除」ボタンが押されると,当該行のデータが削除される仕組みです。このためにSELECTの出力結果の先頭に削除用のフォームを追加します。

PHPスクリプト: select_delete.php(改良部分のみ表示)

このフォームをサブミットすると,不可視(type="hidden")のinputタグ(name="hidden_id")に埋め込まれたid番号がdelete.phpに送られます。

従って,フォームのデータが送られるdelete.phpはこのid番号を受け取り($_POST['hidden_id']または$_REQUEST['hidden_id']に格納されている),先ほど定義したsanitize関数を使ってサニタイズ処理を行ってSQL命令(DELETE)を発行させればよいということになります。どのように改良すればいいか,自分で考えて正しく当該データの削除処理ができることを確認して下さい。これは皆さんへの課題とします。

既存データを更新する(select_update.php作成とupdate.phpの改良)

既存データの更新も,select.phpを改変することで楽に行うことができます。データは既にあるものなので,ユーザの負担を減らすためにも,既存データを最初からフォームに入れておくと良いでしょう。

select_update.php完成イメージ

削除と同様に,select.phpをコピーしてselect_udpate.phpを作り,下記のようにwhileループ内を書き換えます。

PHPスクリプト: select_update.php(改良部分のみ表示)

update.phpには更新されたデータのid, name, size, memoが送られてきます。これをどのようにサニタイズしてupdate.php内でSQL文として組み立てたらよいでしょうか? これは皆さんへの課題とします。

update.phpの改良が終わったら,実際に更新処理ができることを確認しましょう。きちんと動作することが確認できたら,index.htmlにselect_update.phpへのリンクを追加しておいて下さい。

完成!

以上で,データの閲覧(select.php),追加(insert.php),削除(select_delete.php→delete.php),更新(select_update.php→update.php)が可能なCRUD Webアプリが完成したことになります。下記の項目から全ての処理が正常に動くことを再度確認して下さい。

CRUD Webシステム完成後のトップページ

最後に,このCRUD Webアプリのリンク関係を図にしてみましょう。すべてのHTMLファイル,PHPスクリプトがどのようは役割を果たし,どのようにリンクされ状態遷移するのか,人に説明できる図を書けるようになって初めてWebアプリは完成したことになります。

CRUD Webアプリ ファイル関係図

この最小限のCRUD Webアプリはまだまだ機能的に不足しているところがあります。すぐにできそうな改良は

等がありますし,発展的に他のアプリに衣替えさせることも可能です。自由制作のアイディアづくりの土台として参考にして下さい。


Copyright (c) 2014-2017 幸谷研究室 @ 静岡理工科大学 All rights reserved.
Copyright (c) 2014-2017 T.Kouya Laboratory @ Shizuoka Institute of Science and Technology. All rights reserved.