ウエブAPIを用いた初めてのCGI (準備編) プログラム演習2

ヤフー検索APIを用いて、簡単なキーワード検索が可能なサイトを開発します。その前に、初めてのCGI開発なので準備段階として以下のサイトを制作します

【サイトの仕様】

  • 検索窓と検索ボタンを設置します
  • 検索窓にキーワードを入力し、検索ボタンをクリックできるようにします
  • 検索ボタンをクリックするとCGIが起動しますがなにも結果が表示されなくて構いません。ただし、検索窓からキーワードが消えないようにしてください。
  • デバック(開発時の確認要情報)として ログにCGI起動&終了時刻、入力キーワードが確認できるようにしてください

perl

bash-3.2$ cat /Applications/MAMP/htdocs/prog2/index.pl 
#!/usr/bin/perl

use strict;
use warnings;
use CGI;

print STDERR `date` . " script start\n";

my $cgiObj = new CGI;
my $script_name = ($ENV{'SCRIPT_NAME'} =~ m|/([^/]*)$|)[0];

print "Content-type: text/html\n\n";

print<<EOM;
<html>
<head>
<title>Sample Program 2 perl-1</title>
<meta http-equiv="Content-Type" content="text/html" charset="utf-8">
</head>
<body>
EOM

print '<form action="./' . $script_name . '">';
print '<input type="input" name="query" value="'. $cgiObj->param('query') . '">';
print '<input type="submit" value="search">';
print '</form>';

print<<EOM;
</body>
</html>
EOM

print STDERR "query=" . $cgiObj->param('query');
print STDERR `date` . " script end\n";

exit;

ユーザからの入力はQUERY_STRING環境変数から取得できることを前回説明しましたが key1=val1&key2=val2... を毎度解析していたら手間がかかります。ウエブに限らず、プログラムを開発する際は各言語には汎用的なライブラリ集が提供されていることが一般的です。 perl では cpan, PHP では pear と呼ばれるライブラリ提供サイトが一例としてあります。これらを別途ダウンロード&インストールして開発するプログラムから利用することで、プログラムを簡略化することが可能です。上の例ではCGIライブラリ

use CGI;

を呼び出しており、この機能を用いてURLリクエストの変数を取得しています。 利用頻度が高く汎用的はものは言語インストールにあわせて、標準的にインストールされ、利用することもできます。

my $cgiObj = new CGI;
$cgiObj->param('query');

で、query=apple であった場合、 apple という値が返却されます。

CGIと日本語(ダブルバイト文字列)】
URLで日本語を扱う場合, URLからその値をCGIに渡す場合は、その文字列をURLエンコードの変換を行う必要があります。formから入力された場合は自動的にその変換が行われ、URLは
http://.../index.php?query=%E3%83%A9%E3%83%BC%E3%83%A1%E3%83%B3
という形式で渡ります(ブラウザによってはアドレスバーにはデコードさえ日本語で表示される場合があります)
よって上に例では $cgiObj->param('query') は "ラーメン" という文字列になります. ライブラリによってはURLエンコードのままの文字列が返却され、デコードの処理をおこなって日本語文字列が必要になりますが use CGIの場合はデコードはライブラリ内部で行ってくれます。

また、CGIで日本語を扱う場合、その文字コードを意識する必要があります。文字コードutf-8, eucjp, shift-jis の3種がありますが、それぞれのコードで日本語文字のバイトコードがことなるので、当然URLエンコード後の文字列もことなります。デコードした場合は、元の文字コードでの日本語にもどります。今回のサンプルではhtmlのheadに

<meta http-equiv="Content-Type" content="text/html" charset="utf-8">

としている部分で utf-8で扱っていることになります。

apacheはアクセスごとに accesslog および必要に応じて errorlog が記録されてます。各ログファイルはhttpd.confに定義さてており、例えば MAMP環境では、

ErrorLog /Applications/MAMP/logs/apache_error_log

と記述さてています。CGI標準エラー出力に出力することでここにその情報が書き込まれます。

PHP

bash-3.2$ cat index.php 
<?php
    error_log('script start');
print<<<EOM
<html>
<head>
<title>Sample Program 2 php-1</title>
<meta http-equiv="Content-Type" content="text/html" charset="utf-8">
</head>
<body>
EOM;

    print '<form action="./'. basename($_SERVER['SCRIPT_NAME']) .'">';
    print '<input type="text" name="query" value="' . $_GET['query'] . '">';
    print '<input type="submit" value="search">';
    print '</form>';

print<<<EOM
</body>
</html>
EOM;
    error_log('query=' . $_GET['query']);
    error_log('script end');

    exit;

?>

PHPはウエブ開発に特化した言語であるため、色々な箇所で、便利な前処理がされていたり、関数が標準で提供されています。 CGIの引数はプログラムに渡された時点で

$_GET   $_POST   $_REQUEST

の変数に引数 key&valのハッシュ型で保存されています。 例えばGET で渡された query=... の値は

$_GET['query']

で取得できます。またエラーログに書き込む関数 error_log もあります (apacheのエラーログとは別でPHP実行定義ファイルの php.ini で定義されている)

PHPで開発する際にPHP環境変数(php.ini)の
display_errors = On
とすると、ブラウザでPHPのエラーを確認できるので便利。(公開時にはOffにするべき)