phpからMySQLを操作
データベースへの接続には各種情報が必要
$mysqli = new mysqli("localhost", "user", "password", "database");
- localhost
- user
- password
- database
- ↑↑↑↑MAMP画面の「Open WebStart page」押すとブラウザ開く
- そのページの下部に情報が表示されている
- ↑↑↑↑接続するデータベース名は実際に作成したデータベースの名前
sample01.php
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
echo 'DBに接続しました';
?>
</body>
http://localhost:8888/phpsql/sample01.php
- 以上でひとまず接続はできる
- localhostでうまくいかない場合、IPアドレス指定でうまくいく場合がある。
- ただwindowsの場合MAMPに記載がなかったが…
SQLの発行
- phpからSQLを実行する方法
- 一番シンプルなものがqueryメソッド
テーブルの作成
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$db->query('create table test(id INT)');
echo 'テーブルを作成しました';
?>
</body>
-
$db->query('create table test(id INT)');
を追記 - ブラウザで表示(接続)確認
- データベース確認すると「test」というテーブルが追加されている
- idというカラムが「INT」でできている
テーブルの削除
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$db->query('drop table test');
// $db->query('create table test(id INT)');
echo 'テーブルを削除しました';
?>
</body>
-
$db->query('drop table test');
→dropは削除となる - データベース見ると「test」のテーブルが削除されている
応用
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$db->query('drop table if exists test');
$db->query('create table test(id INT)');
echo 'テーブルを削除して、作成しました';
?>
</body>
- testというテーブルがあれば、削除
- testというテーブルを作成
という順序で記述されているのでデータベースにはtestテーブルが作成された状態
SQLのエラー表示に関して
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$db->query('dr table if exists test');
$db->query('create table test(id INT)');
echo 'テーブルを削除して、作成しました';
?>
</body>
- 「drop」がうまく記述されていないが、ページの表示にはエラーが出ない
- phpのエラーは感知できるが、SQL文としてのエラーはphp側で通常チェックすることはできないので。
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$db->query('drop table if exists test');
$success = $db->query('cr table test(id INT)');
if($success){
echo 'テーブルを削除して、作成しました';
}else{
echo 'SQLが正常に動作しませんでした';
echo $db->error;
}
?>
</body>
- queryのメソッドは失敗すると「false」が返ってくる
- 「success」の変数にqueryのメソッドを格納、true・false判定ができるようにしてif文に。
- 「create」が正しく記述できていない形で、上記のように設定
- 正常に動作しませんでした、という表示とともにエラー文も表示されている(エラー位置など)
正しく書くと…
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$db->query('drop table if exists test');
$success = $db->query('create table test(id INT)');
if($success){
echo 'テーブルを削除して、作成しました';
}else{
echo 'SQLが正常に動作しませんでした';
echo $db->error;
}
?>
</body>
-
ちゃんと記述するとtestテーブル追加されている
-
queryメソッドは変数などと組み合わせると危険なので、あくまで例としてとらえておく
select構文の実行
結論
- queryとfetch_assocを組み合わせるとページに表示する形を作ることができる
手順
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$records = $db->query('select * from my_items');
var_dump($records);
?>
</body>
object(mysqli_result)#2 (5) { ["current_field"]=> int(0) ["field_count"]=> int(7) ["lengths"]=> NULL ["num_rows"]=> int(5) ["type"]=> int(0) }
- select文を変数に格納してvar_dumpすると、レコードがとれていることがわかる
実際にテーブルの中身を表示させてみる
商品を表示
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$records = $db->query('select * from my_items');
if($records){
while($record = $records->fetch_assoc())
echo $record['item_name'] . '<br>';
}
?>
</body>
- $recordsに格納したSQL文がエラーなければtrueなので、if文の条件にする
- fetch_assoc()はデータを1件取り出す、という処理
fetchがデータの取り出し、assocが連想配列、みたいな意味 - 連想配列の形で$recordsの配列の中に入っていく
- そちらをechoで表示している
- ※「item_name」はデータベースの内容に連動する(変更すると別のものを表示できる)
priceを表示
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$records = $db->query('select * from my_items');
if($records){
while($record = $records->fetch_assoc())
echo $record['price'] . '<br>';
}
?>
</body>
echo $record['price'] . '<br>';
- ここを「item_name」から「price」に変えるだけでpriceの値を表示できる
複数表示もできる
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$records = $db->query('select * from my_items');
if($records){
while($record = $records->fetch_assoc())
echo $record['price'] . ',' . $record['item_name'] . '<br>';
}
?>
</body>
- priceとitem_nameどちらも表示
補足(while文)
- while文は指定した条件式が真(true)の間、繰り返し実行
- データを全部取り出し終わるとfalseが返るので処理が終わる
while (条件式){
実行する処理1;
実行する処理2;
}
補足(foreachでも書ける)
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$records = $db->query('select * from my_items');
if($records){
while($record = $records->fetch_assoc()){
echo $record['item_name'] . '<br>';
}
}
?>
</body>
↓↓↓↓↓↓↓↓↓このように書き替え可能
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$records = $db->query('select * from my_items');
if($records){
foreach($records as $record) {
echo $record['item_name'] . '<br>';
}
}
?>
</body>
- 複数表示も同様に可
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$records = $db->query('select * from my_items');
if($records){
foreach($records as $record) {
echo $record['price'] . ',' . $record['item_name'] . '<br>';
}
}
?>
</body>
countの結果を表示
php上で実行したい
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$records = $db->query('select count(*) from my_items');
if($records){
while($record = $records->fetch_assoc())
echo $record['count(*)'] . '<br>';
}else{
echo $db->error;
}
?>
</body>
- 上記のように表示できる
- データベース上で行っていた「as」を使ってわかりやすく管理したい
asの表記【count(*) ではなくcntとして表示】
select count(*) as cnt from my_items
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$records = $db->query('select count(*) as cnt from my_items');
if($records){
while($record = $records->fetch_assoc())
echo $record['cnt'] . '<br>';
}else{
echo $db->error;
}
?>
</body>
- select文にasの記述を追加
- while文の表記もcntに変更できる
- ページの表示は変わらず
- 今回の変更はページ表示上は特にメリットないが、php内のコードとしてはcntにすることで管理がしやすくなっている
phpでデータベースにデータを挿入
- まずデータベースに新しくテーブルを追加(memos)
memoにデータを挿入
insert into memos (memo) values ('メモです');
作成したメモのテーブルにphpからデータを入れていく
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$db->query('insert into memos (memo) values("PHPからのメモです")');
echo 'データを挿入しました';
?>
</body>
insert into memos (memo) values("PHPからのメモです")
- こちらの記述でinsertが実行される
- ※phpのクォーテーションとSQLのクォーテーションが混同しないために「'」「"」シングルダブルを使って記述している
- データベース確認するとphp側の追加が反映されている
エラーの判定も置きたい場合
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$ret = $db->query('insert into memos (memo) values("PHPからのメモです")');
if($ret){
echo 'データを挿入しました';
}else{
echo $db->error;
}
?>
</body>
- insertをqueryメソッドで書くことはほぼ無い!
- あくまで例として書いている状態
phpでSQLを組み立てる
- prepareについて
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$message = 'フォームから入力した値';
$stmt = $db->prepare('insert into memos(memo) values(?)');
$stmt->bind_param('s', $message);
$ret = $stmt->execute();
if($ret){
echo 'データを挿入しました';
}else{
echo $db->error;
}
?>
</body>
- 以上でデータの挿入が行える
エラー表示位置などを修正すると下記
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$message = 'フォームから入力した値';
$stmt = $db->prepare('insert into memos(memo) values(?)');
if(!$stmt){
die($db->error);
}
$stmt->bind_param('s', $message);
$ret = $stmt->execute();
if($ret){
echo 'データを挿入しました';
}else{
echo $db->error;
}
?>
</body>
-
$message = 'フォームから入力した値';
→挿入するメッセージを設定 -
$stmt = $db->prepare('insert into memos(memo) values(?)');
- prepareを使ってSQLを組み立てる
- 「query」を用いると危険なのでprepareを用いる
- prepareは「?」をSQLに入れることができる
- 「?」の内容は後の記述で「bid_param」を使って指定することができる
- インサート文に関してはテーブル名(カラム名)で省略せずに記述したパターンの書き方をしている
-
if(!$stmt){ die($db->error); }
→SQL文が正しければこの判定は無視される
「 - die」はメッセージを表示させてそのままプログラムを終了させる、という処理 -
$stmt->bind_param('s', $message);
→「's'」stringという指定。文字列。
※数字は「'i'」。他にもいくつか種類あるが基本sかi。 -
$ret = $stmt->execute();
→「execute();」はSQLを実行する、という意味 -
ややこしいけど覚えてしまえば大丈夫
複数追加もできる
- カラム名を複数に、valuesの「?」も複数にする
- bind_paramの型指定、変数指定も対応した形に変更する
疑問
$stmt = $db->prepare('insert into memos(memo) values(?)');
$ret = $stmt->execute();
ここは実行ではなく格納にしかなっていないのでは?
結論
- オブジェクトのメソッドは代入自体が実行となりそう
以下は検証
<body>
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$message = 'フォームから入力の値02';
$stmt = $db->prepare('insert into memos(memo) values(?)');
if(!$stmt){
die($db->error);
}
$stmt->bind_param('s', $message);
$stmt->execute();
?>
</body>
- このように書き換えても同じように実行はされた。
-
$ret = $stmt->execute();
→$stmt->execute();
オブジェクトの項目にさかのぼって検証
$parent = new ParentClass();
$child = new ChildClass();
$parent->kansuu01('私は');
$child->kansuu01('私は');
$parent->kansuu02();
$child->kansuu02();
- オブジェクトに設定されたメソッドを実行したファイル
変更してみる
$parent = new ParentClass();
$child = new ChildClass();
$test01 = $parent->kansuu01('私は');
$test02 = $child->kansuu01('私は');
$test03 = $parent->kansuu02();
$test04 = $child->kansuu02();
- メソッドをそれぞれ変数に格納する形にしてみたところ、まったく同じようにページが実行された
- オブジェクトの場合は格納自体が実行となると考えてよさそう
フォームと連携したDB操作
input.html
<body>
<form action="input_do.php" method="post">
<textarea name="memo" cols="50" rows="10" placeholder="メモを入力してください"></textarea><br>
<button type="submit">登録する</button>
</form>
</body>
- input_do.phpと連携した簡単なフォームを作成
- テキストエリアに文字を入力して登録するボタンを押すとデータベースにデータを追加する処理
input_do.php
<?php
$memo = filter_input(INPUT_POST, 'memo', FILTER_SANITIZE_SPECIAL_CHARS);
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$stmt = $db->prepare('insert into memos(memo) values(?)');
if(!$stmt){
die($db->error);
}
$stmt->bind_param('s', $memo);
$ret = $stmt->execute();
if($ret){
echo '登録されました';
}else{
echo $db->error;
}
?>
- 基本的には前回までの内容と同じ。
- 接続方法、内容も同じものになっている
-
$memo = filter_input(INPUT_POST, 'memo', FILTER_SANITIZE_SPECIAL_CHARS);
→基本的には$memo = $_POST['memo'];
と書いても接続はできる
しかし危険なプログラムを記入されないような対策のためにfilter_inputで記述している
※書き方はルール、決まった形があるので、その都度調べるなりしたらよさそう - filter_input内の「memo」はinput.htmlのname=memoと対応する
phpでselect構文を表示
- このようにブラウザにメモ一覧を表示させたい
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
$memos = $db->query('select * from memos order by id desc');
if(!$memos){
die($db->error);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>メモ帳</h1>
<?php while($memo = $memos->fetch_assoc()): ?>
<div>
<h2><a href="#"><?php echo htmlspecialchars($memo['memo']); ?></a></h2>
<time><?php echo htmlspecialchars($memo['created']); ?></time>
</div>
<hr>
<?php endwhile; ?>
</body>
</html>
- 以上のように記述する
<?php while($memo = $memos->fetch_assoc()): ?>
<div>
<h2><a href="#"><?php echo htmlspecialchars($memo['memo']); ?></a></h2>
<time><?php echo htmlspecialchars($memo['created']); ?></time>
</div>
<hr>
<?php endwhile; ?>
-
$memo['memo']
メモのカラムと$memo['created']
のカラムを連想配列で取り出す - echoで表示する
-
htmlspecialchars
「htmlspecialchars」の記述を付けるとXSS攻撃を防ぐことができる
DB接続の共通パーツ化
- これまでの手順だと、index.php、index_do.phpのどちらにもDB接続の記述が書かれていた
- 共通箇所はまとめて各ファイルで参照するのがよい
dbconnect.php
<?php
$db = new mysqli('localhost:8889', 'root', 'root', 'db_test');
?>
-
dbconnect.php
を作成して、これまで各ファイルに記述していた接続情報を移植
index.php
<?php
require('dbconnect.php');
$memos = $db->query('select * from memos order by id desc');
if(!$memos){
die($db->error);
}
?>
index_do.php
<?php
$memo = filter_input(INPUT_POST, 'memo', FILTER_SANITIZE_SPECIAL_CHARS);
require('dbconnect.php');
・
・
・
- index.php、index_do.phpでdb接続情報を削除
-
require('dbconnect.php');
→それぞれ呼び出し記述を追加する
見出しを一部だけ表示させる
- 文字数が多いテキストを登録すると表示画面が冗長になる
<h2><a href="#"><?php echo htmlspecialchars(mb_substr($memo['memo'], 0, 50)); ?></a></h2>
-
$memo['memo']
→(mb_substr($memo['memo'], 0, 50)
- 「mb_substr」→文字数の表示を制限できる
- 「0」→開始位置、「50」→文字数制限
- 50文字制限できる
メモ詳細画面を作成
<?php
require('dbconnect.php');
$stmt = $db->prepare('select * from memos where id=?');
if(!$stmt){
die($db->error);
}
$id = 8;
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->bind_result($id, $memo, $created);
$stmt->fetch();
?>
<div><?php echo htmlspecialchars($memo); ?></div>
-
メモのデータを指定して表示させるファイルを作成(memo.php)
-
$id = 8;
の値を変更すると対象のメモが表示される -
$stmt->bind_param('i', 8);
→本来このように直接値を指定したいがbind_paramの特性で直接値を指定できない -
$id = 8; $stmt->bind_param('i', $id);
よって、いったん変数に格納する形で記述している -
queryを使った場合のデータの取り出し方はfetch_assocを使用していた
-
↑↑↑prepareを使った場合の値の取り出し方は
bind_result
を用いる -
bind_result($id, $memo, $created);
変数をの値を指定していく
※データベースから渡ってくる各値をどの変数に格納するかを指定している(渡ってくるのは同じ名前id、memo、createdのカラム) -
fecthはfecth_assocと同じようなもの、データベースからデータを取り出す
詳細ページをURLごとに呼び出す
http://localhost:8888/phpsql/memo/memo.php?id=2
http://localhost:8888/phpsql/memo/memo.php?id=8
- URL末尾が変わると表示するメモを変更した状態になる
<body>
<?php
require('dbconnect.php');
$stmt = $db->prepare('select * from memos where id=?');
if(!$stmt){
die($db->error);
}
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
if (!$id) { // ここから追加
echo '表示するメモを指定してください';
exit();
}
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->bind_result($id, $memo, $created);
$result = $stmt->fetch();
if (!$result) { // ここから追加
echo '指定されたメモは見つかりませんでした';
exit();
}
?>
<div><?php echo htmlspecialchars($memo); ?></div>
</body>
変更箇所
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
- idをこのように変更する
if (!$id) { // ここから追加
echo '表示するメモを指定してください';
exit();
}
- ここはid記入漏れの確認
$stmt->bind_result($id, $memo, $created);
$result = $stmt->fetch();
if (!$result) { // ここから追加
echo '指定されたメモは見つかりませんでした';
exit();
}
- ここは指定されたidのデータが無い場合の確認
メモ一覧からメモ詳細へのリンク
- メモ一覧から各メモ詳細にリンクをつけたい
index.php
<body>
<h1>メモ帳</h1>
<p>→ <a href="input.html">新しいメモ</a>
<?php while($memo = $memos->fetch_assoc()): ?>
<div>
<h2><a href="memo.php?id=<?php echo $memo['id']; ?>"><?php echo htmlspecialchars(mb_substr($memo['memo'], 0, 50)); ?></a></h2>
<time><?php echo htmlspecialchars($memo['created']); ?></time>
</div>
<hr>
<?php endwhile; ?>
</body>
-
<h2><a href="#"><?php echo htmlspecialchars(mb_substr($memo['memo'], 0, 50)); ?></a></h2>
↑↑↑こちらを変更する <a href="memo.php?id=<?php echo $memo['id']; ?>"><?php echo htmlspecialchars(mb_substr($memo['memo'], 0, 50)); ?></a>
- aタグの中身を
<a href="memo.php?id=<?php echo $memo['id']; ?>">
に変更 - memo.php?=の末尾を各idで取得できるような書き方で設定($memo['id']で取得できるということ)
一覧のページネーションを作成
- このようにURL末尾にidをつけることによって5件ずつメモを表示させたい
ひとまずすべての変更は下記(index.php)
<?php
require('dbconnect.php');
$stmt = $db->prepare('select * from memos order by id desc limit ?, 5');
if(!$stmt){
die($db->error);
}
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_NUMBER_INT);
$start = ($page - 1) * 5;
$stmt->bind_param('i', $start);
$stmt->execute();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>メモ帳</h1>
<p>→ <a href="input.html">新しいメモ</a>
<?php $stmt->bind_result($id, $memo, $created); ?>
<?php while($stmt->fetch()): ?>
<div>
<h2><a href="memo.php?id=<?php echo $id; ?>"><?php echo htmlspecialchars(mb_substr($memo, 0, 50)); ?></a></h2>
<time><?php echo htmlspecialchars($created); ?></time>
</div>
<hr>
<?php endwhile; ?>
</body>
</html>
-
$stmt = $db->prepare('select * from memos order by id desc limit ?, 5');
↑↑↑select文を修正。「limit」使用して、5件までの表示にしている。
対象のページidを?に当てはめて変更が効くように設定(?は開始位置)
下部に処理実行可否のif文も記述
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_NUMBER_INT);
$start = ($page - 1) * 5;
$stmt->bind_param('i', $start);
$stmt->execute();
-
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_NUMBER_INT);
↑↑↑filter_input
→POST や GET などの変数をフィルタリングする
filter_input内の「page」はURLに表示されるパラメータの「page」
FILTER_SANITIZE_NUMBER_INT
→数字しか受け取れないようにする処理 -
$start = ($page - 1) * 5;
↑↑↑5件ずつ表示なので、5、10、15と件数を設定するための記述
1→0、2→5、3→10、4→15というように。
<?php $stmt->bind_result($id, $memo, $created); ?>
<?php while($stmt->fetch()): ?>
- ここでバインドしている。
bind_resultにすることによってfetch_assoc()
からfetch()
に変更する
これによって$id
、$memo
、$created
にそれぞれデータベースからの値が入る
各値も直接記述できる-
$memo['id']
→$id
-
$memo['memo']
→$memo
-
$memo['created']
→$created
-
URLパラメータの省略
- URL末尾のパラメータを省くと、何も表示されない
- パラメータない場合は最初のページを表示させたい
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_NUMBER_INT);
if(!$page){
$page = 1;
}
- pageのidが入っていなければ強制的に1を入れる、というだけの処理
ページネーションのリンク作成
- ページ下部にページネーション付けたい
- 1ページは2ページ目のみ表示
- 最終ページは前ページのみ表示にしたい
<p>
<?php if($page>1): ?>
<a href="?page=<?php echo $page - 1; ?>"><?php echo $page - 1; ?>ページ目へ</a>
<?php endif; ?>
<?php if($page<$max_page): ?>
<a href="?page=<?php echo $page + 1; ?>"><?php echo $page + 1; ?>ページ目へ</a>
<?php endif; ?>
</p>
- 表示はこのような形(if文で表示切替)
- 最初のページは単純に1以下なら、という条件
- 最終ページは合計ページ数を計算したうえで条件に組み込む
/* 最大ページ数を求める */
$counts = $db->query('select count(*) as cnt from memos');
$count = $counts->fetch_assoc();
$max_page = floor(($count['cnt']+1)/5+1);
編集画面を作る
update.phpを作成
<?php
require('dbconnect.php');
$stmt = $db->prepare('select * from memos where id=?');
if(!$stmt){
die($db->error);
}
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->bind_result($id, $memo, $created);
$result = $stmt->fetch();
if(!$result){
die('メモの指定が正しくありません');
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>メモの編集</title>
</head>
<body>
<form action="update_do.php" method="post">
<input type="hidden" name="id" value="<?php echo $id; ?>">
<textarea name="memo" cols="50" rows="10" placeholder="メモを入力してください"><?php echo htmlspecialchars($memo); ?></textarea><br>
<button type="submit">編集する</button>
</form>
</body>
</html>
$stmt = $db->prepare('select * from memos where id=?');
if(!$stmt){
die($db->error);
}
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->bind_result($id, $memo, $created);
$result = $stmt->fetch();
if(!$result){
die('メモの指定が正しくありません');
}
- このあたりでデータの取得
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
ここでページURLのidをそのまま取得
<input type="hidden" name="id" value="<?php echo $id; ?>">
<textarea name="memo" cols="50" rows="10" placeholder="メモを入力してください"><?php echo htmlspecialchars($memo); ?></textarea><br>
- このあたりで出力
- 特に難しいことなく、取得したデータもとに
$id
、$memo
記述してるだけ
<input type="hidden" name="id" value="<?php echo $id; ?>">
- インターネットは次のページにしかデータを持ち越すことができない
- その場合、クッキー、ローカルストレージなど用いる
- その他の方法として、隠し項目を設定する方法がある。
- 見えない形のinput項目を設定することでページをまたいでデータを利用できる。
- ユーザーが見えない形でデータの受け渡しを行いたい場合にhiddenで設定するパターンはよくある
update_do.phpを作成
<?php
require('dbconnect.php');
$stmt = $db->prepare('update memos set memo=? where id=?');
if(!$stmt){
die($db->error);
}
$id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);
$memo = filter_input(INPUT_POST, 'memo', FILTER_SANITIZE_STRING);
$stmt->bind_param('si', $memo, $id);
$success = $stmt->execute();
if(!$success){
die($db->error);
}
header('Location: memo.php?id=' . $id);
?>
- ↑↑↑これが完成形
$id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);
$memo = filter_input(INPUT_POST, 'memo', FILTER_SANITIZE_STRING);
- これがupdate.phpから受け取る値
header('Location: memo.php?id=' . $id);
- headerは別のページにジャンプする、というファンクション
- メモの詳細ページに自動で移動するように文字列連結で記述している
削除機能追加
<p><a href="update.php?id=<?php echo $id; ?>">編集する</a> |
<a href="delete.php?id=<?php echo $id; ?>">削除する</a> | <a href="/memo">一覧へ</a></p>
- memo.phpに追記
- 削除に関する記述を追加(削除する)
- delete.phpにリンクを追加
<?php
require('dbconnect.php');
$stmt = $db->prepare('delete from memos where id=?');
if(!$stmt){
die($db->error);
}
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
if(!$db){
echo 'メモが正しく指定されていません';
exit();
}
$stmt->bind_param('i', $id);
$success = $stmt->execute();
if(!$success){
die($db->error);
}
header('Location: index.php');
?>
-
delete.phpを追加
-
ほとんどこれまでと同じ接続情報
-
$stmt = $db->prepare('delete from memos where id=?');
ここが削除処理になっている -
header('Location: index.php');
-
処理が終わったらTOPページに戻る処理