実践編:データベースアプリケーションの作成 前編:PHP4で作るWeb-DBシステム(4)(2/3 ページ)
PHP4プログラミングについてはひととおり理解できたと思う。しかし、まとまった本格的なアプリケーションを開発するとなると話は別で、言語仕様を学んだだけでは十分とはいえない。そこで、最後の仕上げとして本格的なアプリケーションの作成を行う。作業の進め方、プログラミングの考え方についても学んでほしい。
アプリケーションの開発方法
その手段について早速紹介していきたいところですが、ここは焦らずに順を追うことにしましょう。
Webアプリケーションを作成する際に、まず行わなくてはならないのが画面のデザインです。つまり、HTMLを使って静的なWebページを作成するのです。この作業を行ったかどうかが後々まで影響を及ぼしますので、手を抜かずにしっかりとデザインを固めておきたいものです。
今回は、データベースからデータを検索し、更新・削除を行うアプリケーションを作成します。筆者が作成したHTMLと、それをブラウザに表示した画面は、別途図とリストで確認してください(今回は一例を紹介します)。このHTMLのなかで、赤字になっている行は内容が動的に変化する部分です。
このようにして、HTMLのどの部分が動的に変化するのかを把握しておくことも大切です。画面がシンプルなうちは簡単ですが、画面が複雑になるとこうした作業の重要性も増していきます。今回の例のように限られた画面数であればなくてもなんとかなりますが、大規模なアプリケーションであれば画面遷移図なども作っておきたいところです。
少し話がそれてしまいましたが、これからHTMLの動的に変化する部分をPHPに書き換えていきます。
両データベース共通の事柄
■HTMLフォーム
データベースと連携する場合に限らず、動的なページの作成にHTMLフォームを欠かすことはできません。
HTMLフォームとは、<FORM>〜</FORM>のタグで作成する入力画面のことです。HTMLフォームを使えば、入力されたデータをプログラムに引き渡すことが可能になり、そのデータに基づいた処理が行えるようになります。静的なHTMLを動的なプログラムに書き換える際には、このHTMLフォームの加工も忘れないようにしましょう。
HTMLフォームの加工には、大きく分けて2つの重要なポイントがあります。1つは各入力項目のNAMEアトリビュートについて。もう1つはフォームによって起動されるプログラムの設定、すなわちFORMタグのACTIONアトリビュートについてです。
HTMLフォームに入力されたデータは、サブミットボタン(INPUTタグでTYPEがSUBMITに設定されたボタン)を押すことで、指定されたプログラムに引き渡されます。そして、その引き渡すプログラムの設定は、FORMタグのACTIONアトリビュートで行われるのです。そのため、FORMタグの加工を間違えてしまうと、正しいプログラムを呼び出せなくなってしまいます。
そうした間違いをなくすためにも、各画面を生成するプログラムの名称を先に決め、画面遷移図の一部などに記しておくことをお勧めします。そうすることで、HTMLフォームの加工がスムーズになります。通常、こうした作業はシステムの詳細設計の段階で行われることですが、最近では開発期間短縮のために省略されがちです。
設計段階の省力化は開発期間を短くするようにも思えますが、手順を省略しすぎると後で苦労することになりかねません。また、一度プログラムに書き換えてしまうと、なかなか後戻りできないのもWebシステムの特徴です。静的なHTMLを作成しながら画面遷移図などを作り、それから詳細設計に落とし込むようにしたいものです。
■値の受け渡し
またもや話がそれてしまいましたが、次に各入力項目のNAMEアトリビュートについて、注意点を解説しておきます。
PHPの場合、各入力項目に入力された値は、プログラム側の変数に自動的に格納されます。その際、変数の名前は入力項目のNAMEアトリビュートと同じになります。このため、プログラムを作成する前に、入力項目のNAMEアトリビュートに設定する名称を決めておかなくてはなりません。
とはいえ、1つ1つの入力項目について名称を決めていくのは容易ではありません。画面数が多ければ膨大な時間がかかってしまいますし、柔軟な対応ができなくなります。
こうした手間を解消するために命名規則を設けて、例外を除いては機械的に名称を決められるようにしておきます。こうしておけば、HTMLフォーム側とプログラム側で名前が一致しない、といったミスを減らすこともできます。
命名規則の内容はさまざまですが、入力項目が関係するデータベースの列名に“INP_”を付けるなど、分かりやすいルールを決めておけばいいと思います。入力項目の上から順に1、2、3……など、記号的な命名規則にするのはお勧めできません。直感的ではありませんし、なんといっても画面設計の柔軟性がなくなってしまうからです。
1つの例として、今回作成するアプリケーションの画面遷移図とプログラム名の命名を紹介します。それに合わせてHTMLの加工も行ったので図1とリストを参照してください。
テスト用データベースの構築
次に、今回使用するテスト環境について確認しておきたいと思います。今回は社員情報のメンテナンスアプリケーションを例に、図のような2つの表を使用します。この表は、Oracleに標準で添付されているデモデータと同じものです。
データの内容は、図2のとおりです。
■Oracleの場合
Oracleの場合、デモデータは標準で添付されているので特に準備は必要ありません。SQL*PLUSを使って、ユーザー「scott」、パスワード「tiger」でデータベースに接続し、「select * from tab」の結果を見てください。先ほどの表があることを確認できるはずです。
もし、ユーザーscottや表が存在しない場合は以下の手順に従って作成してください。なお、SQLはDBAユーザー(例えばSYSTEM)で実行してください。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
*表領域名は環境によって異なります。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
■PostgreSQLの場合
PostgreSQLの場合はOracleのようなデモデータベースが存在しないので、今回のテスト環境用に自分でデータを用意しなくてはなりません。以前に用意した環境ではinitdbを実行するところ、すなわちデータベースインスタンス(Oracleの「インスタンス」とは少し違うことに注意)の作成まで行いました。この状態で「postmaster -S -i」を実行すれば、PostgreSQLが使える状態になるので一度確認しておいてください(補足1)。
PostgreSQLが使える状態であることを確認したら、createdbコマンドを使ってテスト環境用のデータベースを作成します。これは$POSTGRES_HOMEに格納されているPostgreSQLのコマンドですが、通常のコマンドシェルから実行します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
と入力するとデータベースが作成されると同時に、実行したUNIXユーザーと同じユーザーがデータベースに作成されます。
データベース名は自由に決めることができます。「test」でもいいですし、社員情報という意味で「employee」などでも構いません(例では「employee」という名称を使います)。正常にデータベースが作成されたら、次は「psql」と呼ばれる対話型のSQL実行ツールを呼び出します。Oracleを知る方ならば、SQL*PLUSと同じようなツール、と思っていただけばいいでしょう。
psqlはcreatedbと同じく、コマンドラインから呼び出して実行します。このとき、複数のデータベースが存在する可能性があるため、データベース名をパラメータとして与えます。データベース名が「employee」であれば、
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
と入力します。
ちなみに、「psql -l」と入力すればPostgreSQLに作成されているデータベースの一覧を表示させることも可能です。
psqlを起動すると、プロンプトが「データベース名=#」に変化するはずです(例:employee=#)。ここで試しに「\?」と入力してみてください。「\」を先頭に持つコマンドの一覧が表示されます。これは、バックスラッシュコマンドといって、psqlの機能の一部です(psqlを抜けるには\qとします)。
うまく動作しているようであれば、表(テーブル)を作成するSQLを実行します(リスト1)。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
SQLを実行するときには、リスト1の内容をファイルに保存して、
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
のように入力するとファイルの内容を実行するので便利です。
表が作成されると「create」と表示されますが、実行後に「\d」を入力すれば表の一覧を確認することができます。また「\d 表の名前」とすれば、その表の定義を確認できるので覚えておくといいでしょう。
表が作成できたら、リスト2の内容を使って、データを登録します。先ほどと同じ要領で内容をファイルに保存し、\iコマンドを使って実行させましょう。データ登録後は、念のためにselect文を発行してデータの内容を確認しておいてください。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
補足1 postmasterコマンドは、initdbを実行したユーザーでのみ実行が可能です。以前に用意した環境では、「postgresql」ユーザーを作成していますが、皆さんの環境に合わせて実行してください。また、postmasterが起動しているかどうかはps -auxコマンドで確認してください。以前にも解説しましたが、postmasterコマンドはシステム起動時に自動起動するようにしておくと便利です。
■Oracleを使う上での選択
ところで、PHPとOracleデータベースを組み合わせる場合はここで1つの選択が必要です。PHPにはOracleデータベースと連携するための関数が2種類用意されているからです。それが「Oracle関数」(表1)と「Oracle8関数」(表2)です。
Oracle関数とOracle8関数の違いを簡単に説明すると、OCI8を使っているかどうか、すなわちOracle8クライアントライブラリを使っているかどうかということになります。ここでいうクライアントとは、Webサーバ上にインストールされたクライアントプログラム(Net8 ClientやSQL*PLUSなど)を指します。Oracle8以降のクライアントをインストールしているなら、Oracle8関数を使う方がいいでしょう。
Oracle8関数は、Oracle関数よりも多くの関数が用意されており、機能も豊富です。また、Oracle8関数を使って、Oracle7サーバに接続することも可能です。ただし、PHP4のインストール時(正確にはconfigure実行時)に、OCI8を利用することを宣言していないと使えません。
以前の解説ではOCI8を使うことを明示していませんでしたが、ここではOracle8関数を使って説明していきたいと思います。OCI8の使用を宣言する場合は、configure実行時のオプションとして、「--with-oci8」を付けるようにします。このオプションを使う場合、「--with-oracle」オプションは不要ですので注意してください。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
関数名 | 役割 | 例 | |
---|---|---|---|
Ora_Logon | Oracleへの接続を確立する。 | $conn = Ora_Logon("Scott@ORCL","tiger"); | |
Ora_Logoff | Oracleへの接続を終了する。 | Ora_Logoff($conn); | |
Ora_Open | データカーソルを開く。開いた後はOra_Parseでデータを問い合わせる。 | $cursor = Ora_Open($conn); | |
Ora_Bind | PHPの変数を、Oracle SQLのバインド変数に割り当てる(バインド)。 | Ora_Bind($cursor, "cename", ":wk_ename", 10, 1); | |
Ora_Parse | SQLもしくはPL/SQLブロックを解析させ、指定したカーソルに割り当てる。ただし実行はしない。 | Ora_Parse($cursor, $sql); | |
Ora_Exec | Ora_Parseで解析され、カーソルに割り当てられたSQL、またはPL/SQLブロックを実行する。 | Ora_Exec($cursor); | |
Ora_Fetch | 指定したカーソルにデータセットから、1行分のデータを取得する。 | Ora_Fetch($cursor); | |
Ora_GetColumn | Fetchで取得した行の列データを取得する。 | $cename = Ora_GetColumn($cursor, 1); | |
Ora_Close | Ora_Openで開いたデータカーソルを閉じる。 | Ora_Close($cursor); | |
Ora_ColumnName | 指定したデータカーソル中の列名を取得する。 | $col_name1 = Ora_ColumnName($cursor, 1); | |
Ora_ColumnType | 指定したデータカーソル中の列のデータ型を取得する。 | $col_type1 = Ora_ColumnType($cursor, 1); | |
Ora_Rollback | 実行中のトランザクションをロールバックする。 | Ora_Rollback($conn); | |
Ora_Commit | 実行中のトランザクションをコミットする。 | Ora_Commit($conn); | |
Ora_CommitOff | オートコミット機能をオフにする。オフにしていてもトランザクションは有効。 | Ora_CommitOff($conn); | |
Ora_CommitOn | オートコミット機能をオンにする。 | Ora_CommitOn($conn); | |
Ora_Error | Oracleでエラーが発生したときに、そのエラーメッセージを取得する。 | $err_msg = Ora_Error($cursor); | |
Ora_ErrorCode | Oracleでエラーが発生したときに、そのエラーコードを取得する。 | $err_cd = Ora_ErrorCode($conn); | |
表1 Oracle関数の一覧 |
関数名 | 役割 | 例 | |
---|---|---|---|
OCILogon | Oracleへの接続を確立する。 | $conn = OCILogon("scott", "tiger", "ORCL"); | |
OCIPLogon | Oracleへの持続的接続を確立する。Oracle8以降のデータベースで有効。 | $conn = OCIPLogon("scott", "tiger", "ORCL"); | |
OCINLogon | Oracleへの新規接続を確立する。すでにある接続と明確に区別したい場合に有効。 | $conn = OCINLogon("scott", "tiger", "ORCL"); | |
OCILogoff | Oracleへの接続を終了する。 | OCILogoff($conn); | |
OCINewCursor | データカーソルを開く。開いた後は参照カーソルをバインドするために使用する。 | OCINewCursor($conn); | |
OCIBindByName | 実行するSQLに含まれるバインド変数にPHP変数を割り付けする。 | OCIBindByName($sql, ":empno", &$empno, 4); | |
OCIDefineByName | カーソルで取得する列の値をPHP変数に割り付けする。 | OCIDefineByName($sql, "EMPNO", &$empno); | |
OCINewDescriptor | LOB型やBFILE型のデータを取り扱う際に、記憶領域を確保する。 | $lob = OCINewDescriptor($conn, OCI_D_LOB); | |
OCIParse | SQLもしくはPL/SQLブロックを解析する。ただし実行はしない。 | OCIParse($conn, $sql); | |
OCIExecute | SQLまたは PL/SQLブロックを実行する。Modeパラメータを指定しない場合は、自動的にコミットされる。 | OCIExecute($sql, "OCI_DEFAULT"); | |
OCIFetch | 指定したカーソルにデータセットから、1行分のデータを取得する。 | OCIFetch($sql); | |
OCIFetchInto | 指定した配列にデータセットから、1行分のデータを取得する。 | OCIFetchInto($sql, $emp_array); | |
OCIFetchStatement | 指定した配列にデータセットの全行データを取得する。 | OCIFetchStatement($sql, $emp_array); | |
OCIColumnSize | 指定したデータカーソル中の列のサイズを取得する。 | OCIColumnSize($sql, 1); | |
OCIColumnName | 指定したデータカーソル中の列の名称を取得する。 | OCIColumnName($sql, 1); | |
OCIColumnType | 指定したデータカーソル中の列のデータ型を取得する。 | OCIColumnType($sql, 1); | |
OCIResult | Fetchで取得した行の列データを取得する。 | $nempno = OCIResult($sql, 1); | |
OCIColumnIsNULL | Fetchで取得した行の列データがNULLであるかを確認する。 | OCIColumnIsNULL($sql, 1); | |
OCIRowCount | SQL(Selectは除く)実行時に、操作された行数を取得する。 | $rows = OCIRowCount($sql); | |
OCINumCols | Select操作により取得された行に含まれる列数を取得する。 | $cols = OCINumCols($sql); | |
OCIFreeStatement | 指定したSQLもしくは PL/SQLブロックに関連する全リソースを解放する。 | OCIFreeStatement($sql); | |
OCIFreeCursor | 指定したカーソルに関連する全リソースを解放する。 | OCIFreeCursor($cursor); | |
OCICommit | 実行中のトランザクションをコミットする。 | OCICommit($conn); | |
OCIRollback | 実行中のトランザクションをロールバックする。 | OCIRollback($conn); | |
OCIServerVersion | 指定した接続先のバージョン情報を取得する。 | OCIServerVersion($conn); | |
OCIStatementType | 指定したSQLまたは PL/SQLブロックの種類(SELECT,DELETEなど)を取得する。 | OCIStatementType($sql); | |
OCIError | 直近のエラーに関するメッセージを取得する。 | OCIError($sql); | |
OCIInternalDebug | 内部デバック用出力を有効または無効にする。有効の場合に1。 | OCIInternalDebug(1); | |
表2 Oracle8関数の一覧 |
Copyright © ITmedia, Inc. All Rights Reserved.