目次に戻る
想定外の入力でエラーが発生するケース
まずは名前を「test」として、 welcome.php
を実行しましょう。現在アドレスバーに表示されているURLは
http://localhost/welcome.php?my_name=test
という形になっていると思います。今回はここから色々いじってみます。
1. welcome.php
に直接アクセスされたとき
問題の発生
アドレスバーのURLを http://localhost/welcome.php
にして直接アクセスしてみましょう。
こんにちは、
Notice: Undefined index: my_name in C:\xampp\htdocs\welcome.php on line 20
さん!
という Notice(通知) が発生するはずです。これは7行目、
<p>こんにちは、<?=h($_GET['my_name'])?>さん!</p>
において、 $_GET['my_name']
が未定義(Undefined)だよ! という意味のエラーです。URLからパラメータ my_name
を削ってしまったので、この変数が存在しなくなってしまったのです。
解決策
isset
構文を使って、 $_GET['my_name']
が定義されているかどうか確認します。ここで if
else
文が初登場しますが、
if (/* 条件式 */) {
// 条件式が成立するとき
} else {
// 条件式が成立しないとき
}
というように条件分岐させるためのものだと思ってください。
以下のように welcome.php
の書き換えを行ってください。
<?php
/**
* HTML特殊文字をエスケープする関数
*/
function h($str) {
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
// $_GET['my_name'] が定義されているかどうか調べる
if (isset($_GET['my_name'])) {
// 定義されていればそのまま$my_nameに代入
$my_name = $_GET['my_name'];
} else {
// 未定義ならば「名無し」として設定
$my_name = '名無し';
}
// Content-Typeヘッダー送信
header('Content-Type: application/xhtml+xml; charset=utf-8');
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja">
<head>
<title>Hello!!</title>
</head>
<body>
<p>こんにちは、<?=h($my_name)?>さん!</p>
</body>
</html>
確認
もう一度直接アクセスを行い、「こんにちは、名無しさん!」と表示されれば成功です。
2. welcome.php
に my_name
が配列として渡されたとき
問題の発生
アドレスバーのURLを http://localhost/welcome.php?my_name[a]=b
にして直接アクセスしてみましょう。
こんにちは、
Warning: htmlspecialchars() expects parameter 1 to be string, array given in C:\xampp\htdocs\welcome.php on line 7
さん!
という Warning(警告) が発生するはずです。これは20行目、
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
において、 第1引数 $str
が文字列じゃないといけないのに配列が渡されたよ! という意味のエラーです。配列に関しては後で詳しく学習しますが、イメージとしては最初述べたように箱に例えるならば 「重箱」 に相当します。この例では、
$str['a'] = 'b';
のような形で受け取ってしまっており、 「str」という箱の中にある「a」という箱の中の値が「b」 という状況を示しています。 htmlspecialchars
関数は配列を処理することが出来ないので、このエラーを発生しています。
解決策
is_string
関数を使って、 $_GET['my_name']
が 文字列(String) になっているかどうか確認します。
ここで論理演算子 &&
が初登場しますが、日本語に直訳すると 「且つ」 を意味します。
以下のように welcome.php
の書き換えを行ってください。
<?php
/**
* HTML特殊文字をエスケープする関数
*/
function h($str) {
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
// $_GET['my_name'] が定義されており、且つ文字列であるかどうか調べる
if (isset($_GET['my_name']) && is_string($_GET['my_name'])) {
// 定義されていて文字列であればそのまま$my_nameに代入
$my_name = $_GET['my_name'];
} else {
// 未定義か配列ならば「名無し」として設定
$my_name = '名無し';
}
// Content-Typeヘッダー送信
header('Content-Type: application/xhtml+xml; charset=utf-8');
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja">
<head>
<title>Hello!!</title>
</head>
<body>
<p>こんにちは、<?=h($my_name)?>さん!</p>
</body>
</html>
確認
もう一度直接アクセスを行い、「こんにちは、名無しさん!」と表示されれば成功です。
エラーは発生しないが想定外の入力として処理したいケース
3. 名前が空欄で送信されたとき
問題の発生
form.php
から名前が空欄のまま送信してみましょう。
こんにちは、さん!
このときにもぜひ「名無しさん」と表示させたいですよね。
解決策
!==
演算子を使って、 $_GET['my_name']
が 空欄(空文字列) になっていないかどうか確認します。
以下のように welcome.php
の書き換えを行ってください。
<?php
/**
* HTML特殊文字をエスケープする関数
*/
function h($str) {
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
if (
isset($_GET['my_name']) && // $_GET['my_name'] が定義されており、
is_string($_GET['my_name']) && // 且つ文字列であり、
$_GET['my_name'] !== '' // 且つ空欄でないかどうか調べる
) {
// 条件をすべて満たせばそのまま$my_nameに代入
$my_name = $_GET['my_name'];
} else {
// 1つでも満たさないものがあれば「名無し」として設定
$my_name = '名無し';
}
// Content-Typeヘッダー送信
header('Content-Type: application/xhtml+xml; charset=utf-8');
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja">
<head>
<title>Hello!!</title>
</head>
<body>
<p>こんにちは、<?=h($my_name)?>さん!</p>
</body>
</html>
確認
もう一度空欄にして送信を行い、「こんにちは、名無しさん!」と表示されれば成功です。