PHPで入力値を検査する

(1/1)
PHPのようなサーバサイド・プログラミングでは、クライアントから入力されたデータに対して何か処理を行う場面が多い。そこで、入力されたデータが正しいかどうか、事前にチェックする作業が不可避である。入力値が予想外の値であったり、故意にプログラムを破壊するための値を入力される可能性もあるからだ。
これをバリデーション(validation)と呼ぶ。

悪意のある入力への対策については、「PHPセキュリティ対策:正規化した文字列を取り出す」などで述べていくことにするが、ここでは、入力値が正常な範囲にあるかどうかをチェックする方法を紹介する。
通常、入力エラーチェックは JavaScript などクライアントサイドで行うことが多い。ここでは isleap.php と同様、1つのPHPプログラムの中で、入力、エラーチェック、結果出力を行う方法を紹介する。

目次

入力テキストの長さを検査するサンプル・プログラム

まずはPHPのソースプログラムをダウンロードしてほしい。
解凍できたら、input1.php というファイル名で Apacheの仮想ディレクトリが通っているディレクトリにセーブすること。
例によって、画面に表示している行番号は説明の便宜上のものであり、ソースプログラムには含まれていない。

サンプル・プログラムの実行方法

ブラウザから https://localhost/***/input1.php (*** はセーブした仮想ディレクトリ名)と入力すると、テキスト入力を促す画面が表示される。テキストを入力し [実行] ボタンを押下する。10桁を超えて入力しようとするとエラーを表示し、再入力を促す。

入力テキストの長さをチェックする仕組み

  18: $min_length = 3;            //最小長
  19: $max_length = 10;           //最大長
  20: 
  21: //メインプログラム
  22: if (isset($_POST['text']) == FALSE)     $text = '';     //初回起動時
  23: else                                    $text = $_POST['text'];
  24: 
  25: $l = mb_strwidth($text);        //テキストの長さ

isleap.php 同様、HTMLの中にPHPプログラムが入れ子になっている。

入力テキストは <form> タグの <input> で取得する。
あらかじめ、入力テキストの長さの最小値を変数 $min_length に、最大値を $max_length に代入しておく。この値は文字の桁数で、半角文字なら1、全角文字なら2として数えることとする。
ここでは、$min_length に1を代入しているので、「何か文字を入力しなければならない」チェックも兼ねている。チェックする文字列は POST メソッドの名前textとして渡されることにするが、初回起動時はtextは渡されないので変数 $_POST["text"] は存在しない。このままではエラーになってしまうので、関数  isset  を使って場合分け処理を行っている。

関数  mb_strwidth  によって文字列の長さを求める。関数  mb_strwidth  は、ANK文字なら1、マルチバイト文字なら2として数える。ここで、「マルチバイト文字」の定義は処理系によって異なるのだが、日本語の場合、「全角文字」が相当すると考えておけばいいだろう。
シフトJIS文字の場合は関数  strlen  関数でも同じ結果が得られるが、 UTF-8では mb_strwidth を使わないと正しい結果が得られない。

入力が正常の場合と異常の場合

  27: //正常なら入力テキストを表示
  28: if ($l >$min_length && $l <$max_length) {
  29:     $msg = '入力されたテキストは => ';
  30: //未入力
  31: else if ($l <0) {
  32:     $msg = 'テキストを入力してください => ';
  33: //異常なら再入力を促す
  34: else if ($l < $min_length) {
  35:     $msg = 'テキストが短すぎます => ';
  36: else if ($l > $min_length) {
  37:     $msg = 'テキストが長すぎます => ';
  38: }
  39: echo "<form action=\"input1.php\" method=\"post\">\n";
  40: echo $msg;
  41: echo "<input type=\"text\" size=\"20\" name=\"text\" value=\"" . $text . "\">\n";
  42: echo "<input type=\"submit\" value=\"実行\">\n";
  43: echo "</form>\n";

文字列の長さが $min_length 以上、$max_length 以下なら、正常系の処理を行う。ここでは単に文字列を表示するだけである。
異常入力の場合は、入力文字が短いのか長すぎるのか表示して、再入力を促す。初回入力時もここにジャンプする。

入力値が数字かどうかを検査するサンプル・プログラム

まずはPHPのソースプログラムをダウンロードしてほしい。
解凍できたら、input2.php というファイル名で Apacheの仮想ディレクトリが通っているディレクトリにセーブすること。
例によって、画面に表示している行番号は説明の便宜上のものであり、ソースプログラムには含まれていない。

サンプル・プログラムの実行方法

ブラウザから https://localhost/***/input2.php (*** はセーブした仮想ディレクトリ名)と入力すると、テキスト入力を促す画面が表示される。テキストを入力し [実行] ボタンを押下する。数字以外が入力されているをエラーを表示し、再入力を促す。

入力テキストが数字かどうかをチェックする仕組み

   1: <!DOCTYPE html>
   2: <html lang="ja">
   3: <head>
   4: <meta charset="UTF-8">
   5: <title>入力テキストのエラーチェック(数字)</title>
   6: </head>
   7: <body>
   8: 
   9: <?php
  10: // ここからPHPプログラム ===================================================
  11: /**input2.php
  12:  * 入力テキストのエラーチェック(数字)
  13:  * @copyright   (c)studio pahoo
  14:  * @author      パパぱふぅ
  15:  * @version     2.0  2014/07/12  HTML5対応,表示方式変更
  16:  * @version     1.0  2004/10/12
  17: */
  18: //メインプログラム
  19: if (isset($_POST['text']) == FALSE)     $text = '';     //初回起動時
  20: else                                    $text = $_POST['text'];
  21: 
  22: $l    = mb_strwidth($text);         //テキストの長さ
  23: $flag = is_numeric($text);          //テキストが数字かどうか

プログラムの大部分は input1.php と同じである。

関数  is_numeric  は、引き数が数字かどうかを調べる。数字なら TRUE を、数字以外の文字が混ざっていれば FALSE を返す。
そこで TRUE なら正常系の処理を行い、そうでなければ再入力を促す。初回入力時もここにジャンプする。

isで始まる関数には、変数の値をチェックできるものが複数用意されている。入力チェックに使えるだろう。

半角英字で始まり、2文字目以降が半角英数字かどうかを検査するサンプル・プログラム

まずはPHPのソースプログラムをダウンロードしてほしい。
解凍できたら、input3.php というファイル名で Apacheの仮想ディレクトリが通っているディレクトリにセーブすること。
例によって、画面に表示している行番号は説明の便宜上のものであり、ソースプログラムには含まれていない。

download プログラムを実行する

download ダウンロード(PHP8対応)

サンプル・プログラムの実行方法

ブラウザから https://localhost/***/input3.php (*** はセーブした仮想ディレクトリ名)と入力すると、テキスト入力を促す画面が表示される。テキストを入力し [実行] ボタンを押下する。数字以外が入力されているをエラーを表示し、再入力を促す。

正規表現によるパターンマッチング

  15: $pattern = '/^[A-Z|a-z][0-9|A-Z|a-z]+$/u';
  16:                             //チェックするパターン(perl互換正規表現)
  17: 
  18: //メインプログラム
  19: if (isset($_POST['text']) == FALSE)     $text = '';     //初回起動時
  20: else                                    $text = $_POST['text'];
  21: 
  22: $l    = mb_strwidth($text);                 //テキストの長さ
  23: $flag = preg_match($pattern, $text);        //テキストが数字かどうか

プログラムの大部分は input2.php と同じである。
しかし、入力されたテキストが「半角英字で始まり、2文字目以降が半角英数字である」かどうかを調べる組み込み関数は存在しない。このような込み入った判定を行う際に活躍するのが 正規表現 である。
PHPには POSIX および Perl 互換の正規表現を行う関数群が揃っている。「半角英字で始まり、2文字目以降が半角英数字である」をPerl互換正規表現で記述すると、
/^[A-Z|a-z][0-9|A-Z|a-z]+$/

/.../ で囲んだ部分が正規表現であることを示す。

^ は文字列の先頭を示す。$ は文字列の末尾を示す。
[A-Z] は文字A~Zのいずれかとマッチするクラスで、[A-Z|a-z]は文字A~Zまたはa-zにマッチするクラスである。[0-9|A-Z|a-z] は文字0~9またはA~Zまたはa-zにマッチする。
+ は直前の文字の1回以上の繰り返しを指す。

入力テキストと正規表現のマッチングを行うのが関数  preg_match  である。マッチしたら TRUE、そうでなければ FALSEを返す。
そこで、TRUE なら正常系の処理を行い、そうでなければ再入力を促す。初回入力時もここにジャンプする。

Perl互換正規表現の詳細については、https://jp2.php.net/manual/ja/ref.pcre.php をご覧いただきたい。

正規表現の応用

正規表現を使えば、さまざまな入力チェックを行うことができる。
たとえばメールアドレスのチェックなら、「英小文字で始まり、2文字目以降は英小文字または数字、途中に@が入り、英小文字または数字、途中に.(ドット)が入り、英小文字または数字が続く」というルールにしておけば、
/^[a-z][0-9|a-z]+@[0-9|a-z]+\.[0-9|a-z|\.]+$/

と記述できる。実際のメールアドレスには_(アンダーバー)などが利用できるので、もう少し工夫する必要はある(「正規表現でメールアドレスかどうかチェックする」参照)。

マルチバイト文字(全角文字)に対応するPOSIX互換正規表現マッチング関数 [mb_ereg_match] もある。これを使えば、機種依存文字でないかどうかチェックすることもできる。

正規表現の使い方については、「PHPで正規表現」で解説しているので、ご覧いただきたい。

参考サイト

(この項おわり)
header