2003年度後期 IT教育基礎論演習B

第9回: Webプログラミング(1) 〜 PHP基礎

概要と目標

■ 概要

WWWにおいて、ユーザとのインタラクションのあるページや、 データベースを利用したwebアプリケーションを作成するための スクリプト型プログラミング言語としてPHPを例にとり、 そのプログラムの記述方法、実行方法を習得する。

■ 目標

目次


演習内容

■ はじめに〜PHPとは

PHP(PHP: Hypertext Preprocessor)は、 HTMLの中で使用できるスクリプト型プログラミング言語の一種である。 HTMLファイルの中に、PHPのプログラムを直接書き入れることにより、 ユーザからの入力を受け付けるwebページや、 またその結果を出力するwebページなどを容易に作成することができる。

このようなwebページに利用可能なスクリプト型言語としては JavaScriptなど多数あるが、 JavaScriptがwebブラウザ側で実行されるのに対し、 PHPで記述されたスクリプトはwebサーバ側で実行され、 その出力結果がwebブラウザに渡される方式となっている。 このため、webブラウザの種類や設定に依存せず、 また、各種データベースにアクセスし、そのデータを利用するなど、 複雑な処理を必要とするプログラムを比較的容易に作成することができる。 そのかわり、PHPを利用するためにはwebサーバがPHPのプログラムを解釈できるように 設定されていることが必要であり、 また、JavaScriptやFlashのように、 アニメーションなどによる動きのあるwebページを作成することはできない。

なお、PHPは、現在開発が進められているプログラミング言語であり、 複数の異なるバージョンが利用されている状態にあるが、 本演習では、バージョン4(通称、PHP4)を利用することとする。

■ プログラムの記述と実行

□ PHPスクリプトの記述方法

PHPのプログラムは、HTMLファイルの本文中に、 PHPのスクリプト(各命令を順番に並べた手続き)を "<?"と">"で囲んだ形で記述される。 このとき、PHPスクリプトが記述されたHTMLファイルは、 PHPスクリプトが記述されているファイルであることがwebサーバに判るよう、 拡張子として".html"の替わりに".php"を使用する (注: webサーバの設定により異なる。 PHP3とPHP4の両方を利用できるように設定している場合、 ".php4"とするところも多い。)。

例えば、簡単な例として、 PHPスクリプトを埋め込んだHTMLファイルを 以下のように記述することができる。

簡単なPHPの例: php-sample.php
<html>

<head>
<title>PHP sample</title>
</head>
 
<body>

<?php
/* php-sample.php */

echo("Hello, world!");
?> </body> </html>

このように、PHPのプログラムはHTMLファイルの中に埋め込まれたスクリプトの形で 記述されるが、以降、PHPスクリプトの記述例は、 特に断わらない限りスクリプト部分とその両端のタグの部分のみを 掲示することとする。 サンプルプログラムを入力し、実行する際には、 適宜、HTMLファイルの必要箇所を補って入力すること。

なお、PHPスクリプトのHTMLファイル中への記述方法には、 "<?php"と"?>"で囲む方法以外に、 "<?"と"?>"で囲む方法や、 "<script language="php">"と "</script>"で囲む方法、 "<%"と"%>"で囲む方法も利用できる。 すなわち、表1に示す4種類の記述は、ほぼ同様の働きをする。 "<?php"と"?>"で囲む方法が、 もっとも一般的であるので、これを利用するとよい。

表1: PHPスクリプトの記述方法の種類
タグ 記述例
<?php ... > <?php echo("Hello, world!"); ?>
<? ... ?> <? echo("Hello, world!"); ?>
<script language="php"> ... </script> <script language="php"> echo("Hello, world!"); </script>
<% ... %> <% echo("Hello, world!"); %>

□ PHPスクリプトの実行方法

PHPスクリプトを実行するには、 そのPHPスクリプトが記述されたHTMLファイルをwebサーバを介して取得すればよい。 すなわち、webブラウザなどのwebクライアントからURLによりそのファイルを参照する。 例えば、php-sample.phpが、 http://voyager.ei.tohoku.ac.jp/~takashi/seminar-B-2003/php-samples/php-sample.php として置かれている場合、webブラウザにこのURLを指定し、参照すると、 以下のような結果を得る (注: PHPのスクリプトはwebサーバ上で実行され、 その実行結果がwebブラウザに渡されるため、 webブラウザからPHPスクリプトの記述されたファイルを直接開いても、 正しい結果は得られないことに注意)。

Hello, world!

webサーバを介してPHPスクリプトが記述されたHTMLファイルを取得すると、 webサーバは、PHPスクリプトの部分を実行し、 得られた実行結果をもともとそのスクリプトが記述されていた場所と置き換えた HTMLファイルをwebクライアントに送信する。 従って、php-sample.phpの実行結果として得られるHTMLファイルの内容は、 以下のようになる。

php-sample.phpの実行結果として得られるHTMLファイルの内容
<html>

<head>
<title>PHP sample</title>
</head>

<body>

Hello, world!

</body>
</html>
演習

php-sample.phpを入力し、実行せよ。 またこの時、HTMLファイルの内容が変更されていることを webブラウザのソースを参照する機能を利用し、確認せよ。

■ 言語仕様

文法など、PHPの言語仕様に関しては、 詳細なマニュアルが web上で公開されているので、 詳しくはこのマニュアルを参照することとし、 ここでは、簡単にふれることとする。

□ 書式

PHPスクリプトの書式は、C言語とよく似ている。 PHPの各命令は、1つの命令毎に";"で区切った式として記述する。 また、多くの基本的な命令が関数の形式で提供されている。 例えば、文字列を出力する命令であるecho()関数を利用する場合、 以下のように、記述することができる (注: echo()は正確には関数ではなく言語構造であり、 括弧を付けず","で区切った複数の引数を取ることができる)。

echo("こんにちは");

また、以下のように"/*"と"*/"で囲まれた部分や、 1行の中の"//"以降の部分はコメントであり、実行に影響を与えない。

/* コメント1 */
// コメント2

□ 変数と型

変数の利用

PHPで変数を利用する場合、C言語等と異なり、 変数名の前に"$"を付けて記述する。 例えば、変数$nに数値を代入するには、以下のように記述する。

$n = 1;

このとき、変数を利用するにあたり、その変数を宣言する必要はなく、 変数の型は、値を代入する際に動的に決定され、 基本的に、任意の型の値を変数に自由に代入することができる。 PHPで利用可能な基本型には、表2に示す8種類がある。

表2: PHPで利用可能な基本型
種類
スカラー型 論理値(boolean)
整数(integer)
浮動小数点数(float)
文字列(string)
複合型 配列(array)
オブジェクト(object)
特別な型 リソース(resource)
ヌル(NULL)

変数の値を参照する場合には、以下のように記述する。

echo($n);

PHPでは、 以下のようにダブルクォート(「"」)で囲まれた文字列の中で 変数の値を参照することもできる。

echo("Number = $n");

ただし、シングルクォート(「'」)囲まれた文字列の中では、 "$"があっても変数とはみなされず、"$"がそのまま出力される。 また、ダブルクォート(「"」)で囲まれた文字列の中で "$"を出力したい場合には、 "\$"のように"$"の前に"\"を記述する。

演習

以下に示す、2つの変数に整数型の値を代入し、 その加算結果を表示するプログラムを入力し、実行結果を確認せよ。

変数の使用例: add.php
<?php
     /* add.php */

     $a = 1;
     $b	= 2;
     echo("\$a = $a, \$b = $b, and \$a + \$b = ");
     echo($a + $b);
?>

add.php の実行結果
$a = 1, $b = 2, and $a + $b = 3

配列変数

PHPで配列を利用する場合、C言語等と同様に、 以下のように配列変数名の後ろに"["と"]"で囲って 添え字を指定する。

配列変数の使用例: array-sample.php
<?php
     /* array-sample.php */

     $today = 2;

     $week[0] = "Sunday";
     $week[1] = "Monday";
     $week[2] = "Tuesday";
     $week[3] = "Wednesday";
     $week[4] = "Thursday";
     $week[5] = "Friday";
     $week[6] = "Saturday";

     echo($week[$today]);
?>

また、以下のように、array()関数を利用して 配列の各要素にまとめて代入することもできる。

array()関数を使用した配列変数への代入: array-sample-2.php
<?php
     /* array-sample-2.php */

     $today = 2;

     $week = array("Sunday", "Monday", "Tuesday", "Wednesday",
                   "Thursday", "Friday", "Saturday");

     echo($week[$today]);
?>
連想配列

PHPでは、配列の添え字として文字列を指定し、 対応する要素を参照することのできる連想配列を使用することができる。 例えば、曜日の略記から、正確な表記を得るために、 連想配列を以下のように利用することができる。

連想配列の使用例: associative-array-sample-1.php
<?php
     /* associative-array-sample-1.php */

     $today = date("D");

     $week["Sun"] = "Sunday";
     $week["Mon"] = "Monday";
     $week["Tue"] = "Tuesday";
     $week["Wed"] = "Wednesday";
     $week["Thu"] = "Thursday";
     $week["Fri"] = "Friday";
     $week["Sat"] = "Saturday";

     echo($week[$today]);
?>

文字列を配列の添え字として使用する場合に、 array()関数を使用して各要素をまとめて代入する場合、 以下のように添え字と要素の値を"=>"で区切って記述する。

連想配列への代入: associative-array-sample-2.php
<?php
     /* associative-array-sample-2.php */

     $today = "tue";

     $week = array("sun" => "Sunday",
		 "mon" => "Monday",
		 "tue" => "Tuesday",
		 "wed" => "Wednesday",
		 "thu" => "Thursday",
		 "fri" => "Friday",
		 "sat" => "Saturday");

     echo($week[$today]);
?>
配列の要素

PHPでは、変数に値を代入する際に、その変数の型が動的に決定され、 任意の変数に任意の型の値を代入することができる。 同様に、配列や連想配列の要素の場合にも、任意の値を代入することができる。 すなわち、C言語における配列では同じ型のデータしか代入できなかったのと異なり、 PHPでは、異なる型を要素として持つ配列や、 他の配列を要素として持つ配列など、 複雑なデータ構造を柔軟に定義することができる。

例えば、異なる型のデータを要素として持つ配列の配列を利用して、 以下のようなプログラムを記述することができる。

複雑なデータ構造による配列: array-of-array.php
<?php
    $persons = array("tora"     => array("name" => "Masayuki Torai",
					 "age" => 34,
					 "gender" => "male"),
		     "takoshi"  => array("name" => "Takoshi Yotsuashi",
					 "age" => 33,
					 "gender" => "male"),
		     "tamochan" => array("name" => "Yuji Tameyama",
					 "age" => 33,
					 "gender" => "male"),
		     "izumin"   => array("name" => "Yasuto Izumikawa",
					 "age" => 32,
					 "gender" => "male"),
		     "momo"     => array("name" => "Yuichi Ogawa",
					 "age" => 29,
					 "gender" => "male"));

    $id = "takoshi";
    $key = "name";

    $person = $persons[$id];
    $value = $person[$key];

    echo( "$id 's $key is $value" );
?>
演習

文字列を添え字とした配列を利用し、 学籍番号を添え字とし、氏名を値とする名簿の配列を作成し、 自分の学籍番号から氏名を出力するプログラムを作成せよ。

特別な変数

PHPでは、予め値が定義されている特別な変数がある。 詳しくはPHPのマニュアルの定義済みの変数を参照すること。

□ 制御構造

PHPでは、C言語と同様にif文やswitch〜case文による条件分岐、 for文やwhile文などによる繰り返しなどの制御構造を利用できる。

例えば、if文を利用し、以下のように条件分岐を行なうプログラムを記述できる。

if文による条件分岐の例: if-sample.php
<?php
     /* if-sample.php */

     $today = date("D");
     echo("Today is $today. ");

     if( $today == "Tue" ) {
         echo("We have seminar on fundamentals of IT education B.<br>");
	 echo("Study hard!!");
     } else {
         echo("We don't have seminar on fundamentals of IT education B.<br>");
	 echo("Take a rest, please.");
     }
?>

また、以下のようにfor文による繰り返し処理を行なうプログラムを記述できる。

for文による繰り返し処理の例: for-sample.php
<?php
     /* for-sample.php */

     $k = 1;
     $n = 10;
     $s = 0;

     for($i = $k; $i <= $n; $i++ ) {
         $s = $s + $i;
     }

     echo("Summation from $k to $n makes $s.");
?>

switch 〜 caseによる条件分岐や、whileによる繰り返しも同様に利用できる。

またPHPでは、他のスクリプト言語と同様に、 与えられた配列、もしくは連想配列の要素の数だけ繰り返し処理を行なうための foreach文が用意されている。 foreach文の書式は、配列、および連想配列に応じて、以下の2種類がある。

表3: foreach文の書式
配列 foreach(<array> as <valiable>) <procedure>
連想配列 foreach(<array> as <key> => <valiable>) <procedure>

配列を使用したforeachでは、配列<array>の各要素を 順番に変数<valiable>に代入し、 手続き<procedure>を実行する。 例えば、foreach文を利用して、以下のようなプログラムを記述できる。

foreach文による繰り返し処理の例: foreach-sample.php
<?php
     /* foreach-sample.php */

     $o = array("first", "second", "third");

     foreach($o as $n) {
         echo($n);
	 echo(" number
"); } ?>

また、連想配列を使用したforeachでは、 連想配列<array>の各要素を 順番に変数<valiable>に代入し、 手続き<procedure>を実行するのは、 配列を使用したforeachと同様であるが、 同時に、連想配列の各キーを 変数<key>に代入する点が異なる。 例えば、連想配列を使用したforeach文により、 以下のようなプログラムを記述できる。

foreach文の別書式による繰り返し処理の例: foreach-sample-2.php
<?php
     /* foreach-sample-2.php */

     $o = array("1st" => "first", "2nd" => "second", "3rd" => "third");

     foreach($o as $k => $n) {
	 echo($k);
	 echo(" means ");
	 echo($n);
	 echo(".<br>");
     }
?>

□ 関数

PHPでは、手続きに名前をつけて関数として定義し、利用することができる。 ただし、関数を定義するためには、C言語と異なり 関数を定義することをfunction文により明示する必要があり、 また、引数や戻り値の型は指定しない。

例えば、与えられた2つの値を加算する関数add()を定義し、 利用するプログラムは以下のように記述できる。

関数の定義と利用: add-func.php
<?php
     /* add-func.php */

     function add( $arg1, $arg2 ) {
       return $arg1+$arg2;
     }

     echo( add( 1, 2 ) );
?>

■ フォームからの入力

HTMLのフォームと、PHPを組み合わせることにより、 ユーザからの入力を受け付けるページを容易に作成することができる。

フォームにより入力された値をPHPにより処理するには、 <form>タグのオプションであるactionに PHPスクリプトを記述したファイルを指定する。 フォームにより入力された値は、 入力方式として選択した"POST"もしくは"GET"に応じて、 フォームの<input>タグのnameオプションで 指定された名前をキーとする 特別な配列変数"$_POST"もしくは"$_GET"に代入され、 PHPのプログラムに渡される。

注意!!

フォームから入力された文字列を そのまま出力結果に利用してはならない。

もし、入力された文字列をそのまま出力すると、 間違ってHTMLのタグを入力してしまった場合に その後の表示が崩れてしまうばかりでなく、 悪意のある利用者から問題のあるJavaScriptのコードを入力され、 セキュリティ上の問題となることもある。

この問題を回避するためには、 PHPで提供されているhtmlspecialchars()関数を利用し、 出力文字列中の "<" や ">" など、HTMLとして特別な意味を持つ文字を 出力用の "&lt;" や "&gt;" に置き換えるとよい。

例えば、簡単な例として、次のような入力ページとしてのHTMLと PHPスクリプトを記述することができる。

フォームによる入力: form-input.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<meta http-equiv="content-type" content="text/html;charset=EUC-JP">

<html>

<head>
<title>form input sample</title>
</head>

<body>

<form action="form-process.php" method="POST">
  Please select your gender:
  <input type="radio" name="gender" value="Mr.">Gentleman or 
  <input type="radio" name="gender" value="Ms.">Lady, <br>
  and may I have you name?
  <input type="text" name="yourname" size="30" value="Takoshi YOTSUASHI">
  <input type="submit" name="enter" value="submit">
</form>

</body>
</html>

フォームによる入力の処理: form-process.php
<?php
    echo("Hi, ");
    echo(htmlspecialchars($_POST["gender"]));
    echo(htmlspecialchars($_POST["yourname"]));
    echo(". How are you?");
?>

この実行結果は、以下のようになる。

フォームによる入力例

Please select your gender: Gentleman or Lady,
and may I have you name?

ボタンを押した結果
Hi, Mr.Takoshi YOTSUASHI. How are you?

演習

フォームから学籍番号を入力すると、 対応する学生の氏名を出力するプログラムを作成せよ。

■ 図形やグラフの出力

GDライブラリを組み込んだPHPでは、イメージを扱う様々な関数が用意されており、 これを利用して、図やグラフを出力することができる。

例えば、以下のプログラムを実行することにより、 多角形を描いたページを作成することができる (注: この例では、描かれた結果がJPEG画像としてブラウザに渡されるため、 HTMLの部分を記述する必要はないが、 代わりに、Header()関数により 内容の形式を指定する必要がある)。

多角形の描画: star.php
<?php
    /* star.php */

    Header("Content-type: image/png");

    $r = 100;
    $w = 100;

    $im = ImageCreate($w * 2, $w * 2);
    $black = ImageColorAllocate($im, 0, 0, 0);
    $white = ImageColorAllocate($im, 255, 255, 255);
    $yellow = ImageColorAllocate($im, 255, 255, 0);

    $points = array(
        $w - $r * cos( M_PI/2 ),            $w - $r * sin( M_PI/2 ),
        $w - $r * cos( M_PI/2 - 4*M_PI/5 ), $w - $r * sin( M_PI/2 - 4*M_PI/5 ),
        $w - $r * cos( M_PI/2 + 2*M_PI/5 ), $w - $r * sin( M_PI/2 + 2*M_PI/5 ),
        $w - $r * cos( M_PI/2 - 2*M_PI/5 ), $w - $r * sin( M_PI/2 - 2*M_PI/5 ),
        $w - $r * cos( M_PI/2 + 4*M_PI/5 ), $w - $r * sin( M_PI/2 + 4*M_PI/5 ),
        $w - $r * cos( M_PI/2 ),            $w - $r * sin( M_PI/2 )
    );

    ImageFilledRectangle($im, 0, 0, $w, $w, $black);
    ImageFilledPolygon($im, $points, 6, $yellow );

    ImagePNG ($im);
    ImageDestroy ($im);
?>

このプログラムをwebブラウザから参照すると、 PNG形式の画像が生成され、webブラウザ上に表示される。 もし、インラインイメージとして表示したい場合には、 以下のように<img>タグの引数として、 PHPのスクリプトを指定すればよい。

<img src="php-samples/star.php">

star.phpの実行結果

フォームのGETメソッドを利用してPHPスクリプトに値を渡すことにより、 その値に応じた図形を描画することもできる。 例えば、以下のようなプログラムにより、 GETメソッドにより指定された横幅の矩形を描画することができる。

GETメソッドによる横幅を指定した矩形の描画: bar.php
<?php
    /* bar.php */

    Header("Content-type: image/png");

    $height = 10;
    $width = $_GET["amount"] * 5; // GETメソッドによる値の取得

    $im = ImageCreate($width, $height);
    $black = ImageColorAllocate($im, 0, 0, 0);
    $blue = ImageColorAllocate($im, 0, 0, 255);

    ImageFilledRectangle($im, 0, 0, $width - 1, $height - 1, $blue);
    ImageRectangle($im, 0, 0, $width - 1, $height - 1, $black);

    ImagePNG($im);
    ImageDestroy($im);
?>

このPHPスクリプトをインラインイメージとして使用し、 以下のようにHTML中にPHPスクリプトを記述することにより、 棒グラフを作成することができる。

棒グラフの描画: histogram.php
<table border="1">
  <tr>
    <th>name</th>
    <th>score</th>
  </tr>
<?php
    $students = array("Masayuki Torai" => 86,
		      "Takoshi Yotsuashi" => 33,
		      "Yasuto Izumikawa" => 78,
		      "Yuji Tameyama" => 67,
		      "Yuichi Ogawa" => 92);

    foreach( $students as $name => $score ) {
      echo("<tr>");
      echo("<td>$name</td><td><img src=\"bar.php?amount=$score\"></td>");
      echo("</tr>");
    }
?>
</table>

histogram.php の実行結果
name score
Masayuki Torai
Takoshi Yotsuashi
Yasuto Izumikawa
Yuji Tameyama
Yuichi Ogawa

このほか、イメージ処理のための各種関数が多数用意されている。 詳細に関しては、PHPのマニュアルの イメージ関数 などを参照すること。

レポート課題

■ レポート課題1

為替レートを 1USD(アメリカドル)=110.43円、 1EUR(ユーロ)=128.55円、1GBP(イギリスポンド)=184.78円、 1CHF(スイスフラン)=82.77円とし、 フォームから円を入力し、また変換したい通貨を選択し、OKボタンを押すと、 指定された通貨へ変換するプログラムを作成せよ。

■ レポート課題2

(1)

連想配列を使用して、学籍番号をキーとし、 氏名を値とする学生名簿を定義し、 フォームから学籍番号を入力すると、対応する学生がいる場合はその氏名を出力し、 対応する学生がいない場合、そのような学生はいないというメッセージを出力する プログラムを作成せよ。 プログラムには、3名以上の学生を登録せよ。

(2)

連想配列を使用して、学籍番号をキーとし、 表3、表4に示すデータ構造からなる学生情報を要素とする学生名簿を定義し、 フォームから学籍番号を入力すると、 対応する学生がいる場合はその学生の学籍番号、氏名、年齢、性別を表形式で、 また各科目毎の進捗状況をヒストグラムおよび数値により出力し、 対応する学生がいない場合、そのような学生はいないというメッセージを出力する プログラムを作成せよ。

表3: 学生情報のデータ構造
キー
name氏名
age年齢
gender性別
courses履修科目進捗状況(表4)
表4: 履修科目進捗状況
キー
履修科目名1(A〜任意)進捗状況(%)
履修科目名2(A〜任意)進捗状況(%)
......
履修科目名n (A〜任意)進捗状況(%)

プログラムには、3名以上の学生を登録し、 また、結果には、2コース以上の科目を履修している学生を表示した結果を示せ。

参考書籍、Web

  1. 上ヶ迫 勝憲 著:「図解・標準 最新PHPハンドブック」, 秀和システム, ISBN4-7980-0417-0, ¥2,500-
  2. トビアス・ラチチュラー, ティル・ガーケン 著, 玉川 竜司 訳: 「PHP4でつくるWebアプリケーション」, ピアソン・エデュケーション, ISBN4-89471-454-X, ¥3,600-
  3. PHP日本語マニュアル翻訳プロジェクト: 「PHP日本語マニュアル」,
    http://www.php.net/manual/ja/
  4. 奥村 晴彦: 「PHPによるWebプログラミング」,
    http://www.matsusaka-u.ac.jp/~okumura/php/
Last modified: Tue Dec 09 00:31:04 JST 2003