LoginSignup
2
1

More than 3 years have passed since last update.

生PHPについて知識を資産化していく③

Last updated at Posted at 2021-04-04

前提として

  • 自分が勉強してきた知識を保存するために書いています。
  • 本当に初歩的な事から書いていってます。
  • 万が一間違っている可能性もございますので、その時はご指摘頂ければ嬉しいです。
  • 常時更新していく予定です。
  • アウトプット用ですので、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で起動する

お問い合わせフォームの内容を入れていく

新規作成する

new.png

データベースを作成する

①データベース名を入れる ※例: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;

氏名だけ取り出す

それぞれの氏名だけ取り出せました!!
↓↓

氏名取り出し2

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でデータベースと接続していく

mainte/db_connection.php
<?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インジェクションを防ぐ対策とは|わかりやすく仕組みを解説

データベースの中身を表示させる

mainte/index.php
<?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"
//  }
// }

?>
mainte/index.php
<?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に保存

お問い合わせフォームで登録した内容をデータベースに保存してみる

mainte/insert.php
// 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の値で間が空いているのは、別で作ったダミーデータを消したため)

ダミーデータ反映

お問い合わせフォームの完了場所にデータベースを保存するコードを書く

form/input.php
<?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; ?>

?>
mainte/insert.php
<?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についての記事はこちらから
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1