前項では、すでに非推奨となっている MySQL 関数を使用しましたが、
ここでは PDO を使用します。
さらにデータ検索、追加、変更、削除のできるページを作成します。
・一覧・詳細・新規登録・変更・削除は GET の detail, register, modify, delete パラメータ
・新規登録・変更・削除の場合、確認・完了・修正・キャンセルは POST の confirm, complete, correct, cancel パラメータ(ボタンの name 属性)
処理振り分け後、DB 処理を行い、forward または redirect でページ表示を行います。
・forward: require_once member/xxx.php
・redirect: header("Location: member.php?xxx");
ページ一覧
member.php のページ振り分け処理
← 1-2. PHP+MySQL のサンプル
↑ 一覧
ここでは PDO を使用します。
さらにデータ検索、追加、変更、削除のできるページを作成します。
member.php
<?php
/**
* 会員管理コントローラー。
*
* @author 2014/07/13 matsushima
*/
try {
require_once "common.php";
if ("POST" != $_SERVER["REQUEST_METHOD"]) {
if (isset($_GET["detail"])) {
// 詳細: 詳細ページ。
forwardDetail("detail", "detail", null, null);
} else if (isset($_GET["register"])) {
// 登録: 編集ページ。
forwardDetail("register", "edit", null, null);
} else if (isset($_GET["modify"])) {
// 変更: 編集ページ。
forwardDetail("modify", "edit", null, null);
} else if (isset($_GET["delete"])) {
// 削除: 詳細ページ。
forwardDetail("delete", "detail", null, null);
} else {
// 一覧: 一覧ページ。
forwardList();
}
} else {
$model = null;
$validation = null;
if (isset($_GET["register"])) {
if (isset($_POST["confirm"])) {
if (validate("register", $model, $validation)) {
// 登録 > 確認: 詳細ページ。
forwardDetail("register", "detail", $model, $validation);
} else {
// 登録 > 確認 > 入力エラー: 編集ページ。
forwardDetail("register", "edit", $model, $validation);
}
} else if (isset($_POST["complete"])) {
// 登録 > 確認 > 完了: ユーザーを登録 > 一覧ページ。
validate("register", $model, $validation);
processRegister($model);
header("Location: member.php");
} else if (isset($_POST["correct"])) {
// 登録 > 確認 > 修正: 編集ページ。
validate("register", $model, $validation);
forwardDetail("register", "edit", $model, $validation);
} else {
// 登録 > キャンセル: 一覧 or 詳細ページ。
// 登録 > 確認 > キャンセル: 一覧 or 詳細ページ。
header("Location: member.php".($_GET["register"] ? "?detail=".$_GET["register"] : ""));
}
} else if (isset($_GET["modify"])) {
if (isset($_POST["confirm"])) {
if (validate("modify", $model, $validation)) {
// 変更 > 確認: 詳細ページ。
forwardDetail("modify", "detail", $model, $validation);
} else {
// 変更 > 確認 > 入力エラー: 編集ページ。
forwardDetail("modify", "edit", $model, $validation);
}
} else if (isset($_POST["complete"])) {
// 変更 > 確認 > 完了: ユーザーを変更 > 詳細ページ。
validate("modify", $model, $validation);
processModify($model);
header("Location: member.php?detail=".$_GET["modify"]);
} else if (isset($_POST["correct"])) {
// 変更 > 確認 > 修正: 編集ページ。
validate("modify", $model, $validation);
forwardDetail("modify", "edit", $model, $validation);
} else {
// 変更 > キャンセル: 詳細ページ。
// 変更 > 確認 > キャンセル: 詳細ページ。
header("Location: member.php?detail=".$_GET["modify"]);
}
} else if (isset($_GET["delete"])) {
if (isset($_POST["complete"])) {
// 削除 > 完了: ユーザーを削除 > 一覧ページ。
processDelete($_GET["delete"]);
header("Location: member.php");
} else {
// 削除 > キャンセル: 詳細ページ。
header("Location: member.php?detail=".$_GET["delete"]);
}
}
}
} catch (PDOException $e) {
die("エラーが発生しました: ".$e->getMessage());
}
/**
* 入力パラメータ取得・検証。
*/
function validate($func, &$model, &$validation) {
$model["id"] = $_GET[$func];
$model["loginid"] = $_POST["loginid"];
if (!preg_match("/^[a-zA-Z0-9]{1,20}$/", $model["loginid"])) {
$validation["loginid"] = "20文字以内の英数字で入力してください。";
}
$model["password"] = $_POST["password"];
if (!preg_match("/^[a-zA-Z0-9]{1,20}$/", $model["password"])) {
$validation["password"] = "20文字以内の英数字で入力してください。";
}
$model["password2"] = $_POST["password2"];
if ($model["password2"] != $model["password"]) {
$validation["password2"] = "パスワードが異なります。";
}
$model["name"] = $_POST["name"];
if (!preg_match("/^.{1,100}$/", $model["name"])) {
$validation["name"] = "100文字以内で入力してください。";
}
return (count($validation) < 1);
}
/**
* 一覧ページ。
*/
function forwardList() {
// ユーザーを検索
$dbh = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD);
$sql = <<<EOD
select
*
from
user_mst
where
loginid like :keyword
or name like :keyword
EOD;
if ($_GET["sort"]) {
$sql .= "\r\norder by\r\n\t".$_GET["sort"].(!isset($_GET["desc"]) ? ' asc' : ' desc');
}
$stmt = $dbh->prepare($sql);
$stmt->execute([":keyword" => "%".$_GET["keyword"]."%"]);
// 転送
require_once "member/list.php";
$dbh = null;
}
/**
* 詳細ページ。
*/
function forwardDetail($func, $page, $model, $validation) {
// ユーザーを取得
if (null == $model) {
$dbh = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD);
$sql = <<<EOD
select
*
from
user_mst
where
id = :id
EOD;
$stmt = $dbh->prepare($sql);
$stmt->execute([":id" => $_GET[$func]]);
$model = $stmt->fetch(PDO::FETCH_ASSOC);
$model["password1"] = $model["password"];
$model["password2"] = $model["password"];
}
// 転送
require_once "member/".$page.".php";
$dbh = null;
}
/**
* ユーザーを登録。
*/
function processRegister($model) {
// ユーザーを登録
$dbh = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD);
$sql = <<<EOD
insert into
user_mst
(
loginid,
password,
name
) values (
:loginid,
:password,
:name
)
EOD;
$stmt = $dbh->prepare($sql);
$stmt->execute(array_intersect_key($model, ["loginid"=>"","password"=>"","name"=>""]));
$dbh = null;
}
/**
* ユーザーを更新。
*/
function processModify($model) {
// ユーザーを更新
$dbh = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD);
$sql = <<<EOD
update
user_mst
set
loginid = :loginid,
password = :password,
name = :name
where
id = :id
EOD;
$stmt = $dbh->prepare($sql);
$stmt->execute(array_intersect_key($model, ["id"=>"","loginid"=>"","password"=>"","name"=>""]));
$dbh = null;
}
/**
* ユーザーを削除。
*/
function processDelete($id) {
// ユーザーを削除
$dbh = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD);
$sql = <<<EOD
delete from
user_mst
where
id = :id
EOD;
$stmt = $dbh->prepare($sql);
$stmt->execute(["id" => $id]);
$dbh = null;
}
?>
member/detail.php
<?php
/**
* 詳細ページ。
*
* @author 2014/07/14 matsushima
*/
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>members</title>
<link rel="stylesheet" href="/css/default.css" />
</head>
<body id="page">
<!-- ヘッダ -->
<div class="header">
<!-- パンくず -->
<div class="header-inner">
<a href="member.php">ユーザー</a>
<?php if (isset($_GET["detail"])) { ?>
> <a href="member.php?detail=<?=$_GET[$func]?>">詳細</a>
<?php } else if (isset($_GET["register"])) { ?>
> <a href="member.php?register=<?=$_GET[$func]?>">新規登録</a> > 確認
<?php } else if (isset($_GET["modify"])) { ?>
> <a href="member.php?modify=<?=$_GET[$func]?>">変更</a> > 確認
<?php } else if (isset($_GET["delete"])) { ?>
> 削除
<?php } ?>
</div>
</div>
<!-- メイン -->
<div class="main">
<!-- 詳細 -->
<table class="detail">
<tbody>
<?php if (!isset($_GET["register"])) { ?>
<tr>
<th>ID</th>
<td><?=htmlspecialchars($model['id'])?></td>
</tr>
<?php } ?>
<tr>
<th>ログインID</th>
<td><?=htmlspecialchars($model['loginid'])?></td>
</tr>
<tr>
<th>名前</th>
<td><?=htmlspecialchars($model['name'])?></td>
</tr>
</tbody>
</table>
<?php if (isset($_GET["detail"])) { ?>
<form class="form" action="member.php" method="get">
<button name="modify" value="<?=$model['id']?>">変更</button>
<button name="delete" value="<?=$model['id']?>">削除</button>
<button name="register" value="<?=$model['id']?>">コピーして登録</button>
<button>戻る</button>
</form>
<?php } else if (isset($_GET["register"]) || isset($_GET["modify"])) { ?>
登録してよろしいですか?
<form class="form" action="member.php?<?=$func?>=<?=$_GET[$func]?>" method="post">
<input type="hidden" name="loginid" value="<?=htmlspecialchars($model['loginid'])?>" />
<input type="hidden" name="password" value="<?=htmlspecialchars($model['password'])?>" />
<input type="hidden" name="password2" value="<?=htmlspecialchars($model['password2'])?>" />
<input type="hidden" name="name" value="<?=htmlspecialchars($model['name'])?>" />
<input type="submit" name="complete" value="完了" />
<input type="submit" name="correct" value="修正" />
<input type="submit" name="cancel" value="キャンセル" />
</form>
<?php } else if (isset($_GET["delete"])) { ?>
削除してよろしいですか?
<form class="form" action="member.php?<?=$func?>=<?=$_GET[$func]?>" method="post">
<input type="submit" name="complete" value="完了" />
<input type="submit" name="cancel" value="キャンセル" />
</form>
<?php } ?>
</div>
</body>
</html>
member/edit.php
<?php
/**
* 編集ページ。
*
* @author 2014/07/15 matsushima
*/
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>members</title>
<link rel="stylesheet" href="/css/default.css" />
</head>
<body id="page">
<!-- ヘッダ -->
<div class="header">
<!-- パンくず -->
<div class="header-inner">
<a href="member.php">ユーザー</a>
>
<?php if (isset($_GET["register"])) { ?>
<a href="member.php?register=<?=$_GET[$func]?>">新規登録</a>
<?php } if (isset($_GET["modify"])) { ?>
<a href="member.php?modify=<?=$_GET[$func]?>">変更</a>
<?php } ?>
</div>
</div>
<!-- メイン -->
<div class="main">
<!-- 編集 -->
<form class="form" action="member.php?<?=$func?>=<?=$_GET[$func]?>" method="post">
<table class="detail">
<tbody>
<?php if (isset($_GET["modify"])) { ?>
<tr>
<th>ID</th>
<td><?=$model['id']?></td>
</tr>
<?php } ?>
<tr>
<th><label for="loginid">ログインID</label></th>
<td>
<input type="text" id="loginid" name="loginid" value="<?=htmlspecialchars($model['loginid'])?>" />
<label for="loginid" class="error"><?=$validation['loginid']?></label>
</td>
</tr>
<tr>
<th><label for="password">パスワード</label></th>
<td>
<input type="password" id="password" name="password" value="<?=htmlspecialchars($model['password'])?>" />
<label for="password" class="error"><?=$validation['password']?></label>
</td>
</tr>
<tr>
<th><label for="password2">(再入力)</label></th>
<td>
<input type="password" id="password2" name="password2" value="<?=htmlspecialchars($model['password2'])?>" />
<label for="password2" class="error"><?=$validation['password2']?></label>
</td>
</tr>
<tr>
<th><label for="name">名前</label></th>
<td>
<input type="text" id="name" name="name" value="<?=htmlspecialchars($model['name'])?>" />
<label for="name" class="error"><?=$validation['name']?></label>
</td>
</tr>
</tbody>
</table>
<input type="submit" name="confirm" value="確認" />
<input type="submit" name="cancel" value="キャンセル" />
</form>
</div>
</body>
</html>
css/default.css
/**
* デフォルトスタイルシート。
*
* @author 2014/07/14 matsushima
*/
/*
* デザイン
*/
#page .error {
color: red;
}
/*
* ページ
*/
#page {
margin-top: 0px;
}
/*
* ヘッダ
*/
#page .header {
width: 100%;
background-color: #dddddd;
}
#page .header .header-inner {
padding: 5px;
}
/*
* 検索フォーム
*/
#page .form.search {
margin: 1em 0px;
padding: 5px;
background-color: #f1f5ff;
}
/*
* 一覧
*/
#page .list {
margin: 1em 0px;
border-spacing: 0;
border-collapse: collapse;
}
#page .list th,
#page .list td {
border: 1px solid black;
padding: 5px;
}
#page .list thead tr {
background-color: #dddddd;
}
#page .list tbody tr:nth-child(even) {
background-color: #f1fff5;
}
#page img.img_sort {
border: 0px;
margin-top: 2px;
}
/*
* 詳細
*/
#page .detail {
margin: 1em 0px;
}
#page .detail th {
background-color: #dddddd;
text-align: right;
padding: 2px 5px;
}
#page .detail td {
text-align: left;
padding: 2px 5px;
}
一覧(検索)ページ
新規登録ページ
コントローラ: ページ遷移など
すべてのページの URL が member.php になっていて、ページの判別をリクエストパラメータで行います。・一覧・詳細・新規登録・変更・削除は GET の detail, register, modify, delete パラメータ
・新規登録・変更・削除の場合、確認・完了・修正・キャンセルは POST の confirm, complete, correct, cancel パラメータ(ボタンの name 属性)
処理振り分け後、DB 処理を行い、forward または redirect でページ表示を行います。
・forward: require_once member/xxx.php
・redirect: header("Location: member.php?xxx");
ページ一覧
ページ | URL | POSTデータ | 転送先 |
---|---|---|---|
一覧(検索) | GET member.php?条件など | - | forward member/list.php |
詳細 | GET member.php?detail=id | - | forward member/detail.php |
新規登録入力 | GET member.php?register=(コピー元id) | - | forward member/edit.php |
新規登録確認 | POST member.php?register=(コピー元id) | confirm, 入力データ | forward member/detail.php |
新規登録確認(入力エラー) | POST member.php?register=(コピー元id) | confirm, 入力データ | forward member/edit.php |
新規登録完了 | POST member.php?register=(コピー元id) | complete, 入力データ | redirect 一覧 |
新規登録修正 | POST member.php?register=(コピー元id) | correct, 入力データ | forward member/edit.php |
新規登録キャンセル | POST member.php?register=(コピー元id) | cancel, 入力データ | redirect 一覧 or 詳細 |
変更、削除 | 略 |
member.php のページ振り分け処理
if ("POST" != $_SERVER["REQUEST_METHOD"]) { if (isset($_GET["detail"])) { // 詳細: 詳細ページ。 } else if (isset($_GET["register"])) { // 登録: 編集ページ。 } else if (isset($_GET["modify"])) { // 変更: 編集ページ。 } else if (isset($_GET["delete"])) { // 削除: 詳細ページ。 } else { // 一覧: 一覧ページ。 } } else { $model = null; $validation = null; if (isset($_GET["register"])) { if (isset($_POST["confirm"])) { if (validate("register", $model, $validation)) { // 登録 > 確認: 詳細ページ。 } else { // 登録 > 確認 > 入力エラー: 編集ページ。 } } else if (isset($_POST["complete"])) { // 登録 > 確認 > 完了: ユーザーを登録 > 一覧ページ。 } else if (isset($_POST["correct"])) { // 登録 > 確認 > 修正: 編集ページ。 } else { // 登録 > キャンセル: 一覧 or 詳細ページ。 // 登録 > 確認 > キャンセル: 一覧 or 詳細ページ。 } } else if (isset($_GET["modify"])) { if (isset($_POST["confirm"])) { if (validate("modify", $model, $validation)) { // 変更 > 確認: 詳細ページ。 } else { // 変更 > 確認 > 入力エラー: 編集ページ。 } } else if (isset($_POST["complete"])) { // 変更 > 確認 > 完了: ユーザーを変更 > 詳細ページ。 } else if (isset($_POST["correct"])) { // 変更 > 確認 > 修正: 編集ページ。 } else { // 変更 > キャンセル: 詳細ページ。 // 変更 > 確認 > キャンセル: 詳細ページ。 } } else if (isset($_GET["delete"])) { if (isset($_POST["complete"])) { // 削除 > 完了: ユーザーを削除 > 一覧ページ。 } else { // 削除 > キャンセル: 詳細ページ。 } } } | // GET // 詳細 // 詳細 // 新規登録 // 新規登録入力 // 変更 // 変更入力 // 削除 // 削除確認 // 一覧 // 一覧 // POST // 新規登録 // 確認 // 入力 OK // 新規登録確認 // 入力 NG // 新規登録入力 // 完了 // 新規登録完了 // 修正 // 新規登録修正 // キャンセル // 新規登録キャンセル // 変更 // 確認 // 入力 OK // 変更確認 // 入力 NG // 変更入力 // 完了 // 変更完了 // 修正 // 変更修正 // キャンセル // 変更キャンセル // 削除 // 完了 // 変更完了 // キャンセル // 変更キャンセル |
モデル: DB 処理など
$dbh = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD);
DB に接続します。$stmt = $dbh->prepare($sql);
SQL を実行する準備をします。$stmt->execute($model);
準備した SQL を実行します。$model = $stmt->fetch(PDO::FETCH_ASSOC);
select 結果から次の行を取得します。参考サイト:
http://jp1.php.net/← 1-2. PHP+MySQL のサンプル
↑ 一覧