[ホーム] -> [Aache + PHP + PostgreSQL 実験室]

PHP プログラムとして

Hello World * 7

さて、ここまでで説明したことを元に、もう一度 Hello World を表示するPHP ファイルを作ってみたいと思います。ただし、今度は、Hello World の後ろに 1 から 7 の数字を付けて Hello World を7回表示させます。実行した結果が、サンプルの様になれば OK です。

これを実現させるための方法はいくつかありますが、PHP の while 文を必ず使ってください。もちろん、PHP の機能なんか使わなくての可能ですが、復習という意味で、使ってみてください。サンプルソースを3つ載せておきます。別にこの通りでなくてもかまいません。まあ、サンプル3が一番普通でしょう。

GET と POST

PHP 以外で、CGI を作ったことのある方なら分かると思いますが、PHP のプログラムを呼び出すときに、前の画面から値を渡すことができます。これには、GETPOST という方法があります。

GET

まず、GET ですが、これは URL の後ろに、クェッションマーク「?」を置いて、その後ろに引数を書きます。引数は、基本的に「変数名=値」の形式で書きます。複数の値を渡したいときには、間にアンパサンド「&」を入れます。例えば次のようなものです。

showvar_get.php?name=Hizuya&age=23

この例では、二つの引数を渡しています。name というキーに対して Hizuya という値、age というキーに 23 という値です。この値は、呼び出された PHP プログラム、つまり showvar_get.php の中で、$_GET という配列変数を通して参照できます。

つまり、showvar_get.php 内では、$_GET['name']Hizuya という値が、$_GET['age']23 という値が入ってきます。

if ($_GET['age'] >= 20) {
  print(htmlspecialchars($_GET[name]). さんは成年です。");
} else {
  print(htmlspecialchars($_GET[name]). さんは、まだ未成年です。");
}

htmlspecialchars という関数を使っていますが、前の画面から渡された変数を表示するときには必ず利用してください。この関数は、HTML の特殊文字「< > & "」をエスケープし、それぞれ「&lt; &gt; &amp; &quot;」に変換します。これを利用しないと、前の画面で HTML の特殊文字を入力された場合、画面の表示が崩れてしまったりするだけでなく、作り方によっては JavaScript を仕込んだりしてセキュリティ上大変問題になります

POST

GET これに対して、POST というのは、HTML の <form> タグを使います。次のように <form> タグと、<input> タグを組み合わせることにより、ユーザからの入力を促し、その値をプログラムに渡すことができます。

<form action="showvar_post.php" method="POST">
  名前:<input type="text" name="name"><br>
  年齢:<input type="text" name="age"><br>
  <input type="submit" value="Submit">
</form>

この例では、名前と、年齢を入力してもらうようにしています。入力した後、「Submit」というボタンを押すと、<form> タグの action に指定された PHP プログラムが呼び出されます。<form> タグに 「method="POST"」を書くのを忘れないでください(これを書かないと、先ほどの GET と同じになります)。

ここでは、showvar_post.php が呼び出されるプログラムです。先の例と同じように、$_POSTという配列変数を通してPOSTされた値を参照できます。showvar_post.php 内では、$_POST['name']$_POST['age'] という変数に、それぞれ名前と年齢が入ってきます。これは、<input> タグの name 属性に、それぞれ nameage という値を使っているからです。

注意点

どのような場合でも、クライアントより送られてくる値は信用しないで下さい

例えば、<input type="hidden"> を HTML に書いて置いたとします。この hidden の値は変更できないと思う人もいるかもしれませんが、変更することは可能です。変更されると、サーバには変更された値が渡ってくるので、hidden の値を絶対的に信用してはいけません。

ありがちな上、危険なものとして、hidden を使ってキーを保存しておいて、後でそのキーを元に値を更新するような仕組みです。違うキーの値を送られたら、違うデータが更新されます。この場合だと、最低でもそのユーザがそのキーに対して変更が可能かどうかのチェックを入れる必要があります。

あるいは、コンボボックス(<select>)やラジオボタン(<input type="radio">)などは、選択できる値しか送られてこないとの前提でプログラムを作ってはいけません。実際はどんな値でも送ることは可能です。

必ず、選択肢以外の値が入力されたらエラー処理を行うようにしておきましょう。

PHP の設定

PHP の動きを変えるために、PHP にはさまざまな設定値があります。この設定値は、php.ini という設定ファイルに書かれます。このファイルは、このサイトの手順でインストールした場合は /usr/local/apache/conf/php/php.ini にあります。デフォルトだと、/usr/local/lib/php.ini かな? RedHat 系だと、/etc/php/php.ini かもしれません。

このファイルの中を見ると、いろいろ設定が変えられそうです。すべてを説明が必要な人は、マニュアルに書かれているので、それを参照してください。主要なもののみ説明します。

ちなみに、設定ファイル中に、[PHP] だとか、[SQL] の様に、大カッコで囲んだ文字のある行がありますが、これは、「見やすくするための目印」なので、あってもなくても構いません。従って、どの設定をどこに書いても問題ありません。

php.ini の主要な設定
キー 説明
register_globals GET, POST などの値をグローバル変数として登録するかどうかを指定します。今までの説明で、GETname=Seigo などと渡された値は、$_GET['Seigo'] で取得できると説明しましたが、実は $name でも取得できるのです。ですが、セキュリティ上の問題があるので、この設定値を Off にして、$_GET, $_POST を使うようにした方がいいと思います。もし、$name という変数が使えるとしたら、プログラム中で利用している変数を、GET などで値を渡すことにより上書きできてしまうかもしれません(作り方によりますが・・・)。デフォルトで On になっていると思います。
short_open_tag これは、PHP コードを書くのに、<? ?> のペアが利用できるかどうかの設定です。デフォルトで On になっていますが、Off にすると、<? ?> のペアは利用できません。<?php ?> は関係なく利用できます。
asp_tags これは、PHP コードを書くのに、ASP タイプの <% %> のペアが利用できるかどうかの設定です。デフォルトで Off になっていると思います。利用したい場合のみ On にしましょう。
extension_dir PHP は、機能をモジュールとして分割していて、それらを設定ファイルにより、ロードしたりロードしないようにしたりできます。これは、Apache の DSO モジュールと同じです。このサイトの説明ではモジュールを分離させませんでしたが、このサイトで配布している RPM は、モジュール分割しています。このようなモジュールファイルを置いておくディレクトリを指定します。ただし、このディレクトリに置いたからと言って、自動的にロードされるわけではありません。
extension ロードするモジュールを指定します。ロードするには、ここで指定する方法と、dl 関数を利用する方法があります。
sendmail_path PHP の関数の中には、メールを送るものがありますが、そのときに利用する sendmail へのパス(とオプション)を指定します。Windows などで、sendmail が無い場合は、SMTP という設定項目で、SMTP サーバを指定します。
log_errors スクリプトのエラーメッセージをエラーログに保存するかどうかを指定します。エラーが起きた画面を自分が見ているのならいいのですが、たまにしか出ないエラーなどはなかなか気付かないので、On にしておくことをお勧めします。この設定を有効にするには、次の error_log も指定する必要があります。
error_log スクリプトのエラーをログファイルに保存する場合は指定します。ファイルのパスを指定しますが、syslog と記述すると、syslog に保存されます(Windows NT/2000 の場合はイベントログ)。ファイルを指定する場合は、Apache の実行ユーザ(大抵は nobody)ですので、そのユーザが書き込みできないといけません。

実は、これらの設定値は、php.ini 以外でも、Apache の設定ファイルに書くことも可能です。php.ini に書くと、その設定はすべてのファイルに影響してしまいますが、Apache の設定ファイルで書けば、あるディレクトリ以下や、URL、ファイルを限定して設定できます。

<IfModule mod_php4.c>
    php_flag  register_globals Off
    php_value error_log        /var/log/php.log
</IfModule>

このように、「php_flag 設定項目 値」あるいは「php_value 設定項目 値」と書きます。On/Off の設定項目のみ php_flag を使い、それ以外は、php_value を使うようです。

PHP の設定項目の中でも、一部のものは、php_admin_value, php_admin_flag で設定しないと設定できないものもあります。この設定できない項目の場合、Apache の httpd.conf でしか設定できません。それ以外の php_value, php_flag で設定できる項目については、httpd.conf や、.htaccess などで設定できます。どの項目が admin かは、PHP のマニュアルを参照してください(ダウンロードしたマニュアルには記述が無く、PHP のサイトにあるオンラインマニュアルでしか見られないようです)。上の説明した項目の中では、asp_tags, short_open_tag, extension_dir, sendmail_pathadmin でしか設定できないようです。

日本語を使う

現在の PHP は国際化対応され、日本語を使った処理ができますが、それには専用の関数を使わないといけません。「マルチバイト文字列関数」と呼ばれるもので、mb_ で始まる関数群です。例えば、strlen という、文字列の文字数を数える関数がありますが、次のようにすると結果が違います。

<?php
  echo("strlen=".strlen("日本語abc")."\n");
  echo("mb_strlen=".mb_strlen("日本語abc")."\n");
?>

strlen の結果は 9 ですが、mb_strlen の結果は 6 です。mb_strelen の方は、正しい「文字数」を返しています。この様に、「日本語」として正しく処理したい場合は、mb_ が付いているものがあったら、そちらを使うようにしましょう。

いちいち、この関数を使い分けるのが面倒な方には、デフォルトの関数を、マルチバイト対応関数で置き換えてしまう方法も用意されています。PHP の mbstring.func_overload という設定項目に値を設定することで上書きすることができます。

置き換えられる関数
元の関数 置き換える関数
1(メール関連) mail mb_send_mail
2(文字列操作) strlen mb_strlen
strpos mb_strpos
strrpos mb_strrpos
substr mb_substr
4(正規表現) ereg mb_ereg
eregi mb_eregi
ereg_replace mb_ereg_replace
eregi_replace mb_eregi_replace
split mb_split

この設定項目は、書く値の論理和なので、メール関連と文字列操作の関数のみ置き換えたい場合は 3 を、すべての関数を置き換えたい場合は 7 を指定します。また、Apache の設定ファイルで設定する場合は、php_admin_value で設定する必要があるので、httpd.conf でしか設定できません。

日本語を扱う場合、これ以外でも「どの文字コードを使うか」が非常に重要になってきます。日本語の文字コードには、大きく SJIS, EUC-JP, JIS があります。SJIS は Windows で標準で使われていて、EUC-JP は多くの UNIX で使われています。JIS はインターネットメールのやりとりの利用されています。それぞれメリットはありますが、言語として一番無難なのは、EUC-JP でしょう。どの文字コードを使うかどうかは、php.ini や、Apache の設定ファイルで php_value を使うことにより(.htaccess でも)設定できます。

default_charset               = EUC-JP
mbstring.http_output          = EUC-JP
mbstring.internal_encoding    = EUC-JP
mbstring.http_input           = ASCII,JIS,EUC-JP,SJIS
mbstring.detect_order         = ASCII,JIS,EUC-JP,SJIS 
mbstring.substitute_character = none

この設定で、EUC-JP を中心として使うことができます。default_charset は、文字コードの変換とは関係ありませんが、ブラウザに対して、「このページは EUC-JP で書かれてますよ」と教えるための設定です。これにより、ブラウザが間違った文字コードで表示することが無くなります。これに対して、mbstring.http_output は、ブラウザに送るデータ(PHP 処理済みの HTML)を、EUC-JP に変換して送る設定です。

mbstring.internal_encoding は、PHP 内部で文字を処理するときに利用する文字コードです。EUC-JP が無難ですね。SJIS は、問題が多い(2バイト目に、バックスラッシュが使われたりしてる)し、JIS は、エスケープ文字が入っていてどうにもならないので、利用しない方がいいです。

mbstring.http_input は、ブラウザから送られてくる文字を、どの文字コードかを判定するための順番です。この順番で判定し、最初にマッチした文字コードだと認識します。ブラウザは普通、データを送るページの文字コードと同じコードで送ってきますが、まれに違うコードで送ってくる場合があります(送るページの文字コード判定に失敗している場合とか)。このままではコードが違うので文字化けしてしまいますが、この設定により自動的に正しいコードに変換してくれます(過信は禁物ですが)。

mbstring.detect_order は、PHP の文字列中の文字コードを判定するためのコード順です。mbstring.substitute_character はコード変換する際に、コードが変換できない文字とかをどのように扱うかを指定します。none は、変換できない文字は出力しないようにし、long を指定すると、文字コードを 16進数で表示するようにします。

一応、SJIS を標準的に使う場合の設定も載せておきます。i-mode 用のページを作るときとかは、SJIS でないといけません。

default_charset               = Shift_JIS
output_buffering              = On
output_handler                = mb_output_handler
mbstring.http_output          = SJIS
mbstring.internal_encoding    = EUC-JP
mbstring.http_input           = ASCII,JIS,SJIS,EUC-JP
mbstring.detect_order         = ASCII,JIS,SJIS,EUC-JP
mbstring.substitute_character = none

内部コード(mbstring.internal_encoding)と、出力コード(mbstring.http_output)が違う場合、output_bufferingOn に設定し、output_handlermb_output_handler に設定しないといけません。

ホームへ