今度は、サンプルの内容をWebに拡張してみましょう。CGIが使えるWebサーバとMySQLサーバは同一として説明していきますので、別ホストの場合は便宜読み替えて下さい。
<HTML> <HEAD> <META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=x-euc-jp"> <TITLE>MySQLとPerl</TITLE> </HEAD> <BODY> <FORM ACTION="cgi-bin/sample3.cgi" METHOD="POST" ENCTYPE="application/x-www-form-urlencoded"> name:<INPUT TYPE="TEXT" NAME="name" SIZE="12"><BR> memo:<INPUT TYPE="TEXT" NAME="memo" SIZE="12"><BR> <SELECT NAME="command"> <OPTION SELECTED VALUE="insert">追加する(INSERT)</OPTION> <OPTION VALUE="select">表示する(SELECT)</OPTION> <OPTION VALUE="delete">削除する(DELETE)</OPTION> </SELECT> で<INPUT TYPE="SUBMIT" NAME="Submit" VALUE="実行"><BR> </FORM> </BODY> </HTML>
このHTMLではフォームを使っており、リストからコマンドを選択することでINSERT、SELECT、DELETEが扱えるようになっています。CGIスクリプトのパスは、皆さんの環境に合わせて置き換えてください。
次にCGIスクリプトの説明です。ここでは該当行のみを示すとして、リストの全文はリスト4を参照してください。
#!/usr/bin/perl
1行目のPerlのパスは、サーバの環境に合わせましょう。今回はMySQLサーバ連携部分に主を置くため、それ以外は極力省略しています。例えば、CGI.pmを使えばもっとシンプルにフォームの値を取得し(10〜20行目)、htmlヘッダの出力(22〜32行目)も簡略化できますが、34行目以降を注視していきましょう。
SELECTおよびDELETEの処理(34〜66行目)を見ていきましょう。この2つの処理は、INSERTと違い、SQL文の後ろに条件式・WHERE句が付く可能性があります。WHERE句では“like”演算子を使い、部分一致で条件を絞り込んでいます。
if($form{name} ne '' ){ $where .= "name like '\%$form{name}\%'"; }
まず、上記のように35行目でフォームから値:nameが空白かどうか調べ、空白でなければWHERE句に追加します。値:memoについても同じ操作をします(41行目)。
if($form{name} ne '' && $form{memo} ne ''){ $where .= " and " }
また、name、memoがともに記入されていた場合は条件式を“and”でつなぐ必要があります(39行目)。
最後にWHERE句の頭に"WHERE "を付けます(46行目)。49行目からは操作がSELECTかDELETEかで変わります。
print "<h1>該当 $num_rows 件</h1>"; for ($i=0; $i<$num_rows; $i++) { @a = $sth->fetchrow_array; print "<h2>name=$a[0] memo=$a[1]</h2>"; }
SELECTの場合(49〜59行目)は上記のように検索結果を抽出して表示する必要がありますが、DELETEの場合は
print "<h1>削除完了<h1>";
として実行結果だけを返します(60〜65行目)。
61行目では、
$sth = $db->prepare("delete FROM list $where");
にセットされるDELETE文に注意しましょう。$whereが空でなければ条件式に合ったものだけを削除しますが、もし$whereが空の場合、すなわちnameもmemoも何も記入されないまま削除が選択された場合は"delete FROM list"となり、listテーブルにあったすべての値が消されてしまいます。
67〜76行目はINSERTが選択された場合です。まず、何も記入されていないままCGIが実行されても空白を登録することになりますが、当然テーブルの定義がnameを空白として認めていないためエラーになります。
if($form{name} eq '' ){ print "<h1>nameが空白では登録できません</h1>"; }
つまらないエラーを未然に防ぐために、フォームの値が記入されているかを確認します(68〜70行目)。
$sth = $db->prepare("insert into list (name,memo) values ('$form{name}','$form{memo}')"); $sth->execute;
その後検査されたフォームの値でINSERTを行います(71〜74行目)。
$db->disconnect;
最後は礼儀正しくデータベースの接続を解除し(78行目)、
print <<FOOTER; </body> </html> FOOTER
でhtmlを締めくくります(80〜83行目)。
以上、最もシンプルなCGIスクリプトをPerlで記述してみました。CGI.pmを使わない分、煩雑な作業が入っているので可読性が悪くなってしまいましたが、MySQLを操作するロジックはお分かりいただけたと思います。掲示板やチャットなど、CGIの主たるものはほとんどが過去ログをファイルとして保存する仕組みになっていますが、それをMySQLに変えるだけで、ずっとレスポンスは良くなるはずです。
次回はMySQLをPHPで扱えるようにしてみましょう。最近では、多くの紹介記事を目にするようになりました。DB連携Webサーバの紹介でもPerl、Servlet/JSPに並びPHPというのが定石のように取り上げられています。
それではまた次回。
Copyright © ITmedia, Inc. All Rights Reserved.