#前提として
- 自分が勉強してきた知識を保存するために書いています。
- 本当に初歩的な事から書いていってます。
- 万が一間違っている可能性もございますので、その時はご指摘頂ければ嬉しいです。
- 常時更新していく予定です。
- アウトプット用ですので、MAMPを使用していきます。
#####PHPについての記事はこちらから
##データベースと接続
PHPからMySQLデータベースにアクセスするためのAPIは2種類ある(PHP7の場合)
①mysqli
②PDO_MySQL ※こちらで進めていきます
php.net:MySQL用PHPドライバの概要
PHPでデータベースに接続するときのまとめ
###DB(データベース)操作の基本 CRUD
・Create → 新規作成
・Read → 表示
・Update → 更新 ※履歴を残すか、完全に上書きするか
・Delete → 削除 ※完全に消すか、非表示にするか
※データ量が膨大になるなら、
・パーティション(分割)
・レプリケーション(ミラーリング)
これらも要検討する
##phpMyAdmin
MAMPから起動させる
①「Open WebStart page」をクリックする
②ブラウザから、 ツール → phpMyAdminで起動する
お問い合わせフォームの内容を入れていく
####新規作成する
####データベースを作成する
①データベース名を入れる ※例:infoma
②照合順序を選ぶ ※例:utf8_general_ci
####テーブルを作成
テーブル名は複数形で書く
例:users, articles など
①テーブル名を作成 ※複数形で書く!! //ここではcontacts と入力
②カラム数を決める ※今回はid、氏名、メールアドレス、url、性別、年齢、お問い合わせ内容、日付(created, updated)の9つ作成する
###テーブル作成時に抑えたいこと
・ストレージエンジン → 基本はInnoDB
・照合順序 → 現在はutf8mb4推奨
・データ型
・数字(整数(int) 少数(float)、金額なら整数かdecimal)
・文字列(varchar)、boolean(真偽)、Dateなど想定される文字数に合わせる
カラム挿入後
↓↓
###新規作成
「挿入」をクリックして、データを追加する
###更新
作成したデータの横の「編集」をクリック
データ変更後に「実行」すると更新される。
###削除
作成したデータの横の「削除」をクリック
###表示
画面の「インラインを編集」をクリックする
・氏名だけ取り出す
SELECT your_name FROM contact;
それぞれの氏名だけ取り出せました!!
↓↓
###DB操作の基本(SELECT)
・SELECT 表示させたい項目
・FROM table名
・Where 検索条件
・Group by グループ化
・Order by 表示順序
・Join テーブル結合(inner/outer/left)
etc...
##PDO(PHP Data Object)
データベースとやり取りできる方法。
###クラス
関連する機能をひとまとめに(責務の分離)
クラス(class)
変数/定数、関数をひとまとめにしたもの
・変数/定数 → プロパティ
・関数 → メソッド
php.net:PDOクラス
###クラスの使い方
2パターンある
①new(動的)
- $pdo = new class名;
- $pdo->プロパティ
- $pdo->メソッド
②static(静的)
- PDO::ATTR_ERRMODE
- PDO::ERRMODE_EXCEPTION
動的と静的
アロー演算子( -> )とスコープ演算子( :: )
php.net:定義済み定数
###作成したデータベースに接続するためのユーザーを作成する
作成しているデータベースを選んでいる状態で「特権」をクリックする
ユーザーアカウントを追加する
- ログイン情報入力
- 「データベース infoma への全ての特権を与える。」にチェックを入れる
- 「実行」をクリックする
新しいユーザーが追加されました!!
###PDOでデータベースと接続していく
<?php
//指定されたデータベースの接続を表すPDOインスタンスを生成する
const DB_HOST = 'mysql:dbname=infoma;host=127.0.0.1;charset=utf8';
// データベースにアクセスできるユーザー
const DB_USER = 'php_user';
// データベースにアクセスするためのパスワード
const DB_PASSWORD = 'password123';
$pdo = new PDO(DB_HOST, DB_USER, DB_PASSWORD);
// データベースと繋がっているかどうかをチェックする(例外処理) Exception
// トライする処理、エラーが出た時の処理
// try{データベースに接続する方法を書く} catch(PDOExecption $e){
// echo '接続失敗' . $e->getMessage() . "\n";
// exit(); //接続失敗した時に抜ける
//}
try{
$pdo = new PDO(DB_HOST, DB_USER, DB_PASSWORD, [
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,//連想配列
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, //例外
PDO::ATTR_EMULATE_PREPARES => false, //SQLインジェクション対策
echo '接続成功';
} catch(PDOException $e) {
echo '接続失敗' . $e->getMessage() . "\n";
exit;
}
// ログイン画面に設定したユーザー名とパスワードを入れて、合っていれば接続成功と出る
?>
php.net:PDO::__construct
php.net:例外
SQLインジェクションを防ぐ対策とは|わかりやすく仕組みを解説
###データベースの中身を表示させる
<?php
require 'db_connection.php';
// ユーザー入力なし(query)
$sql = 'select * from contacts where id = 4'; //sql文
$stmt = $pdo->query($sql); //sql文実行 ステートメント
$result = $stmt->fetchAll(); //sql文の結果を表示
var_dump($result);
↓↓
// 接続成功
// array(1) {
// [0]=>
// array(9) {
// ["id"]=>
// int(2)
// ["your_name"]=>
// string(9) "あああ"
// ["email"]=>
// string(13) "test@test.com"
// ["url"]=>
// string(15) "http://test.com"
// ["gender"]=>
// int(0)
// ["age"]=>
// int(5)
// ["contact"]=>
// string(9) "テスト"
// ["created_at"]=>
// string(19) "2021-04-03 10:23:42"
// ["updated_at"]=>
// string(19) "2021-04-03 10:24:37"
// }
// }
?>
<?php
require 'db_connection.php';
// ユーザー入力あり(prepare, bind, execute)
$sql = 'select * from contacts where id = :id'; //名前付きプレースホルダ
$stmt = $pdo->prepare($sql); // プリペアードステートメント
$stmt->bindValue('id', 3, PDO::PARAM_INT); //数字の型として 3 が入力させる 紐付け
$stmt->execute(); //実行
$result = $stmt->fetchAll(); //sql文の結果を表示
echo '<pre>';
var_dump($result);
echo '</pre>';
↓↓
// 接続成功
// array(1) {
// [0]=>
// array(9) {
// ["id"]=>
// int(3)
// ["your_name"]=>
// string(9) "いいい"
// ["email"]=>
// string(15) "test2@test2.com"
// ["url"]=>
// string(16) "http://test2.com"
// ["gender"]=>
// int(1)
// ["age"]=>
// int(2)
// ["contact"]=>
// string(10) "テスト2"
// ["created_at"]=>
// string(19) "2021-04-03 10:24:47"
// ["updated_at"]=>
// string(19) "2021-04-03 10:26:21"
// }
// }
?>
php.net:PDOStatement クラス
php.net:プリペアドステートメントおよびストアドプロシージャ
【PHP】PDOの静的プレースホルダと動的プレースホルダの違いを確認する
###トランザクション(まとまって処理)
beginTransaction, commit, rollback
<?php
require 'db_connection.php';
$sql = 'select * from contacts where id = :id'; //名前付きプレースホルダ
$pdo->beginTransaction();
try{
//sql処理
$stmt = $pdo->prepare($sql); // プリペアードステートメント
$stmt->bindValue('id', 3, PDO::PARAM_INT); //数字の型として 3 が入力させる 紐付け
$stmt->execute(); //実行
$pdo->commit(); //全てまとめて処理をする
}catch(PDOException $e){
$pdo->rollBack(); //更新のキャンセル
}
?>
##フォーム値をDBに保存
お問い合わせフォームで登録した内容をデータベースに保存してみる
// DB接続 PDO
require 'db_connection.php';
// 入力 DB保存(ユーザー入力あり) prepare, bind, execute(配列(全て文字列の場合))
//ダミーデータ
$params = [
'id' => null, //AUTO_INCREMENTを設定していて自動的に値が入るのでnull
'your_name' => 'なまえ',
'email' => 'test@test.com',
'url' => 'http://test.com',
'gender' => '1',
'age' => '2',
'contact' => 'いいい',
'created_at' => null, //TIME STAMPは自動的に設定してくれるのでnull
'updated_at' => null //TIME STAMPは自動的に設定してくれるのでnull
];
$count = 0;
$columns = '';
$values = '';
// array_keysで連想配列の左のキーを持ってくる
foreach(array_keys($params) as $key) {
if($count++>0) {
$columns .= ','; //0より大きかったら、「,」をつけて区切っていく
$values .= ','; //0より大きかったら、「,」をつけて区切っていく
}
$columns .= $key;
$values .= ':'.$key; //頭に「:」をつけて名前付きプレースホルダーになる
$sql = 'insert into contacts ('. $columns .')values('. $values .')'; //名前付きプレースホルダー
// var_dump($sql); //$sqlの中身を確認する
// exit; //ここで処理を止めた場合は保存されない。
// ↓↓成功するとこのように表示される
// 接続成功string(166) "insert into contacts
// (id,your_name,email,url,gender,age,contact,created_at,updated_at)values(:id,:your_name,:email,:url,:gender,:age,:contact,:created_at,:updated_at)"
$stmt = $pdo->prepare($sql); // プリペアードステートメント
$stmt->execute($params); //実行 データベースに保存される
↓↓
//接続成功 と出る
?>
接続成功すると、ダミーデータで設定した値が反映される
(idの値で間が空いているのは、別で作ったダミーデータを消したため)
###お問い合わせフォームの完了場所にデータベースを保存するコードを書く
<?php
・
・
・
<?php if ( $pageFlag === 2 ) : ?>
<!-- 合言葉が合っていたか確認する -->
<?php if ($_POST['csrf'] === $_SESSION['csrfToken']) :?>
<!-- DB保存 -->
<?php require '../mainte/insert.php';
// 値を受け渡す
insertContact($_POST);
?>
送信が完了しました。
<!-- 合言葉を削除する -->
<?php unset($_SESSION['csrfToken']); ?>
<?php endif; ?>
<?php endif; ?>
?>
<?php
// DB接続 PDO
function insertContact($request) {
require 'db_connection.php';
// 入力 DB保存(ユーザー入力あり) prepare, execute(配列(全て文字列の場合))
$params = [
'id' => null, //AUTO_INCREMENTを設定していて自動的に値が入るのでnull
'your_name' => $request['your_name'],
'email' => $request['email'],
'url' => $request['url'],
'gender' => $request['gender'],
'age' => $request['age'],
'contact' => $request['contact'],
'created_at' => null, //TIME STAMPは自動的に設定してくれるのでnull
'updated_at' => null //TIME STAMPは自動的に設定してくれるのでnull
];
・
・
・
$stmt = $pdo->prepare($sql); // プリペアードステートメント
$stmt->execute($params); //実行
}
?>
####①お問い合わせフォームから値を入力していく
####②確認画面で問題なければ「送信」ボタンを押す
####③送信完了画面
####④送信完了後、データベースに保存されているか確認する
処理の内容としては、
①お問い合わせフォームの内容を一旦連想配列に入れる
②PDOでデータベースで繋ぐ
③プレースホルダーで値を渡す
④プリペアードステートメントで準備する
⑤executeで実行!!
※SQL文を複数作るなら トランザクション を使う
Laravelなどのフレームワークでは、ORM, OR/マッパーという方法がある
ただ、ベースとなる知識は、
・PDO
・プレースホルダー
・プリペアードステートメント
これらの基盤を抑えるのは大切!!
#####PHPについての記事はこちらから