php講座

入力データの受け取りと処理

フォームデータの受け取り

受け取り
$_GET['変数名'];
  • 変数名←フォームの[name]属性値
  • 値←フォームの[value]属性値
form1.html
<form action="result1.php" method="GET">
…
<select name="blood" size="1">
<option value="no_select">未選択・不明</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="O">O</option>
<option value="AB">AB</option>
</select>
…
</form>
result1.php
<?php
$blood = htmlspecialchars($_GET['blood'], ENT_QUOTES);
//htmlspecialchars(値, ENT_QUOTES) 説明は後で
?>
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <title>結果1</title>
</head>
<body>
<h1>結果1</h1>
<p>あなたは<?php print $blood;?>型です。</p>
</body>
</html>

GETとPOST

GET
結果表示ページのURL
http://…/result1.php?blood=A
POST
結果表示ページのURL
http://…/result2.php
form2.html
<form action="result2.php" method="POST">
…
<select name="blood" size="1">
<option value="no_select">未選択・不明</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="O">O</option>
<option value="AB">AB</option>
</select>
…
</form>
result2.php
<?php
$blood = $_POST['blood'];
?>
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <title>結果2</title>
</head>
<body>
<h1>結果2</h1>
<p>あなたは<?php print $blood;?>型です。</p>
</body>
</html>

複数データ受け取り(チェックボックス)

入力フォーム
※複数回答しても選択結果を一つしか受け取れない
form3.html
<input type="checkbox" name="hobby" value="読書">
<input type="checkbox" name="hobby" value="音楽鑑賞">
<input type="checkbox" name="hobby" value="映画鑑賞">
<input type="checkbox" name="hobby" value="ネット">
<input type="checkbox" name="hobby" value="買い物">
<input type="checkbox" name="hobby" value="ゲーム">
<input type="checkbox" name="hobby" value="スポーツ">
<input type="checkbox" name="hobby" value="その他">
result3.php
<?php
$hobby = $_POST['hobby'];
?>
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <title>結果3</title>
</head>
<body>
<h1>結果3</h1>
<p>あなたの趣味は<?php print $hobby?>です。</p>
</body>
</html>

複数回答を受け取る

PHPではチェックボックスを普通に用いても、複数選択されたデータを受け取ることはできない。PHPでは複数データの受渡は配列を用いる。

その際、入力フォーム側でも修正が必要である。

form3ref.html
<input type="checkbox" name="hobby[]" value="読書">
<input type="checkbox" name="hobby[]" value="音楽鑑賞">
<input type="checkbox" name="hobby[]" value="映画鑑賞">
<input type="checkbox" name="hobby[]" value="ネット">
<input type="checkbox" name="hobby[]" value="買い物">
<input type="checkbox" name="hobby[]" value="ゲーム">
<input type="checkbox" name="hobby[]" value="スポーツ">
<input type="checkbox" name="hobby[]" value="その他">

※フォームタグ内のname属性値に配列を示す[]を付けている

result3ref.php
<?php
$hobbys = $_GET['hobby'];
?>
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <title>結果3</title>
</head>
<body>
<h1>結果3</h1>
<?php
if(count($hobbys) > 0){
?>
<p>あなたの趣味は
<?php
$loopcount = 0;
foreach((array)$hobbys as $hobby){
    $loopcount++;
    print $hobby;
    if($loopcount < count($hobbys)){
        print 'と';
    }
}
?>です。</p>
<?php
}else{
?>
<p>趣味ぐらい持ちなさい!</p>
<?php
}
?>
</body>
</html>

※$_GET['変数名']は配列。

注意点

XSS(クロスサイトスクリプティング)
ユーザが入力するデータはセキュリティホールとなり得る(スクリプトコードを埋め込まれる)。
form4.html
<input type="text" name="text">
result4.php
<?php
$text = $_POST['text'];
?>
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <title>結果4</title>
</head>
<body>
<h1>結果4</h1>
<p>あなたは<q><?php print $text;?></q>と入力しました。</p>
</body>
</html>

対策
string htmlspecialchars('文字列',ENT_QUOTES);
文字列のhtml内での特別な文字を変換する
  • 「<」→&lt;
  • 「>」→&gt;
  • 「"」→&quot;
form4ref.html
中身はform4.htmlと同じ
result4ref.php
<?php
$text = htmlspecialchars($_POST['text'], ENT_QUOTES);
?>
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <title>結果4ref</title>
</head>
<body>
<h1>結果4ref</h1>
<p>あなたは<q><?php print $text;?></q>と入力しました。</p>
</body>
</html>

ログイン認証システム

パスワードの暗号化

パスワードを平文のまま保存するのは危険。なのでサーバには暗号化された状態で保存しておく。

この暗号化パスワードは「不可逆」。

ログイン認証システム

暗号化されたパスワードを用いて、ログイン認証を行う。

不可逆の暗号化がなされているため、入力されたパスワードも暗号化してから、比較する(暗号化したもの同士で比較して等しければ正しいパスワードと見なす)。

login_no_crypt.php
<?php
/***************ログイン情報****************/
//user_id: user
//password: password218
$valid_user_id = 'user';
$valid_password = 'password218';//平文のパスワード
/*******************************************/
$user_id = $_POST['user_id'];
$password = $_POST['password'];
$valid_login = false;

if($_POST['login'] && $user_id == $valid_user_id && $password == $valid_password){
    $valid_login = true;
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <meta name="viewport" content="initial-scale=1.0">
   <title>平文のパスワードを用いた認証システム</title>
</head>
<body>
<h1>平文のパスワードを用いた認証システム</h1>
<?php
if(!$valid_login){
?>
<form action="" method="POST" autocomplete="OFF">
<ul>
<li><label for="user_id">会員ID</label><input type="text" size="10" name="user_id" id="user_id"></li>
<li><label for="password">パスワード</label><input type="password" size="10" name="password" id="password"></li>
</ul>
<button type="submit" name="login" value="login">ログインする</button>
</form>
<?php
    if($_POST['login']){
?>
<p>※会員IDかパスワードが間違っています。</p>
<?php
    }
}else{
?>
<p>ログイン成功!!!!</p>
<?php
}
?>
</body>
</html>
login.php
<?php
/***************ログイン情報****************/
//user_id: user
//password: password218
$valid_user_id = 'user';
$valid_password = '$2y$10$MqkeP6rHjdnsGzkF0lTzvO03eBd8kL2MZ2LGvLkDUXbUpYM4UhHIO';//make_crypt.phpで作成した暗号化済みパスワード
/*******************************************/
$user_id = $_POST['user_id'];
$password = $_POST['password'];
$valid_login = false;

//入力されたパスワードを暗号化して、保存されている暗号化済みパスワードと比較する
//boolean password_verify(検証したいパスワード, 暗号化済みパスワード);
if($_POST['login'] && $user_id == $valid_user_id && password_verify($password,$valid_password)){
    $valid_login = true;
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <meta name="viewport" content="initial-scale=1.0">
   <title>暗号化パスワードを用いた認証システム</title>
</head>
<body>
<h1>暗号化パスワードを用いた認証システム</h1>
<?php
if(!$valid_login){
?>
<form action="" method="POST" autocomplete="OFF">
<ul>
<li><label for="user_id">会員ID</label><input type="text" size="10" name="user_id" id="user_id"></li>
<li><label for="password">パスワード</label><input type="password" size="10" name="password" id="password"></li>
</ul>
<button type="submit" name="login" value="login">ログインする</button>
</form>
<?php
    if($_POST['login']){
?>
<p>※会員IDかパスワードが間違っています。</p>
<?php
    }
}else{
?>
<p>ログイン成功!!!!</p>
<?php
}
?>
</body>
</html>
暗号化パスワードの作成
暗号化パスワードを作成するスクリプト
make_crypt.php
<?php
/********暗号化パスワードを作成するスクリプト*********/

$raw_password = $_POST['password'];
$crypted_password = password_hash($raw_password,PASSWORD_DEFAULT);//暗号化
?>
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <meta name="viewport" content="initial-scale=1.0">
   <title>暗号化パスワードの作成</title>
   <style>
table,th,td{
   border:1px solid black;
}

table{
   border-collapse:collapse;
}
   </style>
</head>
<body>
<h1>暗号化パスワードの作成</h1>
<form action="" method="POST" autocomplete="OFF">
<ul>
<li><label for="password">パスワード</label><input type="text" size="10" name="password" id="password"></li>
</ul>
<button type="submit" name="login" value="login">作成する</button>
</form>
<?php
if($_POST['login'] && $_POST['password']){
?>
<table>
<tr>
<th>入力値</th><td><?php print $raw_password;?></td>
</tr><tr>
<th>暗号化</th><td><?php print $crypted_password;?></td>
</tr>
</table>
<?php
}
?>
</body>
</html>