【DB:結合・レコード】追加/更新/削除の方法

テーブル結合について

2つを1つに

テーブルの結合とは、重複したデータのテーブルを分割しておいて、必要に応じて、仮想的な1つの表として連結して扱う方法。
このようにテーブルを結合することを「リレーション」とか「連結」「関連付け」と呼ぶ場合もある。

■players テーブル
f:id:aruku-hito:20191122210905p:plain

■jobs テーブル
f:id:aruku-hito:20191122210920p:plain

SELECT  :テーブルの指定範囲
LIFT JOIN :の後に追加テーブル名を記述
ON    :結合の共通カラムを=で結ぶ

<?php
    $sql = 'SELECT* FROM players 
                LIFT JOIN jobs
               ON players.job_Id = jobs.id
';
?>

レコード情報について

追加(INSERT INTO)

<?php
//以下のレコード情報を追加したい。
  $name = 'Nakamura';
    $level = 8;
    $job_id = 2;
    
    $sql = 'INSERT INTO players (name,level,job_id) VALUES(:name,:level,:job_id)';
    $statement = $pdo->prepare($sql);
    $statement->bindValue(':name', $name, PDO::PARAM_STR);
    $statement->bindValue(':level', $level, PDO::PARAM_INT);
    $statement->bindValue(':job_id', $job_id, PDO::PARAM_INT);
    $statement->execute();
?>

INSERT INTOの後に テーブル名>カラム名 を記述
そのあとに、値を入れるが変数はNGなので仮で「:〇〇」を追加データ分記述して、それぞれbindValueで変数を代入してあげる。

更新(UPDATE 「テーブル名」SET「更新情報」WHERE 「id指定」)

1.idを指定
2.どのカラムをなんの情報に上書きするかを記述

<?php
    $sql = 'UPDATE players SET level = 10 WHERE id = 11';
    $statement = $pdo->prepare($sql);
    $statement->execute();
?>

削除(DELETE)

<?php
    $sql = 'DELETE FROM players WHERE id = 11';
    $statement = $pdo->prepare($sql);
    $statement->execute();
?>

【DB:出力条件】WHEREを使った書き方

【DB:接続と出力】PDOオブジェクトで、DBにアクセスしてデータを配列に格納するところまではできた。

ただ実際は、ユーザーのアクションごとに必要なテーブルやレコードは変わし、毎回全部読み込んでたら使いたい情報を非常に記述しにくいのでWHEREを使って、SQLの時点で取り出すDB情報を検索するのだ。

f:id:aruku-hito:20191122154418p:plain
今回はplayersテーブルから、主に3パターン紹介
カラム :縦列
レコード:横列

カラムを指定

「この縦列を一気にほしいぜ!」(たぶん比較するのかな?)
sql文に書いていく。

<?php
$sql = 'SELECT name, level FROM players';
    $statement = $pdo->prepare($sql);
    $statement->execute();
?>

f:id:aruku-hito:20191122154954p:plain

条件を指定1

条件の数値や文字が決まっている場合。
「レベル10以上のつわものだけ集え!」「ケンってやつの情報が欲しい!」

<?php
$sql = 'SELECT * FROM players WHERE level >= 10';
    $statement = $pdo->prepare($sql);
    $statement->execute();
?>

f:id:aruku-hito:20191122155419p:plain

<?php
$sql = 'SELECT * FROM players WHERE name = "ケン"';
    $statement = $pdo->prepare($sql);
    $statement->execute();
?>

f:id:aruku-hito:20191122155458p:plain

条件を指定2

条件の数値が変数の場合。
実戦ではこれが圧倒的に多い。なぜならユーザーのアクションごとに使うデータや出力するデータが変動するからだ。
ただし、WHEREの後ろに変数を指定することはできない。(「なんと…!」)

1.いったん「:〇〇」で書く
2.bindValue(Param)メソッドで「:〇〇」と変数名をセットにする

第一引数に「:〇〇」を、第二引数に変数を入れればOK(値を直接入れてもOK)

$low_value = 10 のとき

<?php
$sql = 'SELECT * FROM players WHERE level >= :lower';
    $statement = $pdo->prepare($sql);
    $statement->bindValue(':lower', $low_value, PDO::PARAM_INT);
    $statement->execute();
?>

f:id:aruku-hito:20191122155419p:plain

bindには2種類ある

bindValue

第二引数に入れれるもの
変数:〇
値 :〇
評価:即値をバインド
推奨:文字列の時 第三引数にPDO::PARAM_STRを入れる

※第三引数は入れないとエラーが出る

bindParam

第二引数に入れれるもの
変数:〇
値 :×
評価:実行するとき。つまり、ある変数があるが、executeの手前で変数が変わるとその値をバインドする。
推奨:数値の時 第三引数にPDO::PARAM_INTを入れる

※第三引数は入れないとエラーが出る


===========
参照記事(ありがとうございました!!)
https://qiita.com/tabo_purify/items/0a69fd48018c4ebfd2f2qiita.com

===========

【DB:接続と出力】PDOオブジェクト

「DBに接続してデータを扱いたい」ただそれだけ。

必要な情報

・データベースサーバー:***.sakura.ne.jp (例)
・データベース名:データベース名
・データベースユーザ名:ユーザ名
・データベースパスワード:接続先パスワード

流れ

①DBに接続 (PDO構文)
 ↓
SQLで実行 (SQL構文)
 ↓
③ループ処理で配列にぶち込む (いつものループ処理)

順番に見ていこう。


【前提】
種類:mysql
DB名:mydb
テーブル名:players

①DBに接続 (PDO構文)

まずは、接続。
PHP Data Objects」を略してPDOというデータベース抽象化レイヤというクラスを使う。
これを使うと、世の中に様々なDBの種類があるが、PDOを使えば同じような命令文でアクセスできる
※今まではDBの種類ごとに命令文が違ったりした?らしい…

オブジェクトを作り、引数にDB情報を入れる。

<?php
$pdo = new PDO('mysql:host=localhost; dbname=mydb; charset=utf8','root','パスワード');
?>

SQLで実行 (SQL構文)

つぎに、実行。
「何を実行するねん」と思うが、現状でDBに接続した”だけ”なので、$pdoオブジェクトを活用してデータをとりに”動く”というイメージ。

それにはテーブルとカラムやレコードを選択してどの情報をとるかの選択してから実行する。
最後の2行はテンプレなのでなんとなくでOK。

<?php
$pdo = new PDO('mysql:host=localhost; dbname=mydb; charset=utf8','root','パスワード');

// ▼ SQLで実行 (SQL構文)
$sql = 'SELECT * FROM players';
    $statement = $pdo->prepare($sql);
    $statement->execute();
?>

1行目が大切。ここで$sqlに、テーブルとカラム、レコード、条件を設定する。
※条件設定については次回。

③ループ処理で配列にぶち込む (いつものループ処理)

最後に、データを格納。
要はいつも使ってるような配列に入れること。「良かった~これで見慣れたデータ管理になった!」と思った。
これも見て覚えよう。
※勿論、配列名がresult名である必要はないよ。

<?php
    $result = [];
    while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
		$result[];
	}
?>

これで、配列$resultの要素に1行ずつレコード情報が入った!
fetchは1行ずつ取り出すやつらしい。

ちなみに、WHEREでid指定して1行だけ出力する場合は以下

<?php
  $result = $statement->fetch(PDO::FETCH_ASSOC);
	}
?>

後は、htmlテンプレを読み込んで配列データを煮るなり焼くなりご自由に。


===========
参照記事(ありがとうございました!!)
https://qiita.com/mpyw/items/41230bec5c02142ae691qiita.comhttps://qiita.com/7968/items/6f089fec8dde676abb5bqiita.com
https://gray-code.com/php/connection-db-by-using-pdo/gray-code.com

===========

【フォーム】ラジオ/チェック/プルダウン

結論

type="ここを変えればOK" name="カテゴリ名" value="それぞれ違う値を入れる">項目名

ラジオボタン

1つしか選択できない仕様

htmlで表示する場合

<label for='character'>属性(html)</label>
              <input type="radio" name="character" value="新卒">新卒
              <input type="radio" name="character" value="中途">中途
              <input type="radio" name="character" value="その他">その他
            <p></p>

phpで変数とループ処理で表示する場合

  $business = ['外壁塗装','内装工事','畳張替え'];
            
            <label for='business'>属性(php)</label>
              <?php foreach ($character as $value) { ?>
                <input type="radio" name="character" value="<?= $value ?>"><?= $value ?>
             <?php } ?>

チェックボックス

複数選択できる仕様

htmlで表示する場合

<label for='business'>事業内容(html)</label>
              <input type="checkbox" name="business" value="外壁塗装">外壁塗装
              <input type="checkbox" name="business" value="内装工事">内装工事
              <input type="checkbox" name="business" value="畳張替え">畳張替え
            <p></p>

phpで変数とループ処理で表示する場合
            
            <label for='character'>事業内容(php)</label>
              <?php foreach ($business as $value) { ?>
              <input type="checkbox" name="business" value="<?= $value ?>"><?= $value ?>
              <?php } ?>

こうなります。

f:id:aruku-hito:20191121133604p:plain

注意点

両方とも同じname属性のくくりで並んでいる。
そのため、別のラジオボタンチェックボックスのフォーム項目を組む場合は、name属性を変える。

プルダウン

1つしか選択できない仕様

入力欄。
type属性のよって入力方法を変えることができる。
例)text:フリーテキスト


データを受け取る

action属性で指定したファイルで受け取る。


GETリクエスト:データがURLで引き渡される(検索結果とか)
POSTリクエスト:データがURLで引き渡されない(フォームやパスワードとか)

送信先のファイルで以下の書き方で受け取る。
articleの内容を受け取りたいときは、以下でOK。

$_REQUEST['article'];

【インクルード】共通パーツ

ヘッダーやフッターに多いあれ。
共通デザインを一つのファイルにまとめて、各ファイルからそのファイルにアクセスして表示する仕組み。


include関数

共通部分のhtmlデータを適当に別ファイルにまとめる。
include('ファイル名');で呼び出したい箇所に記述するだけ。

// ▼▼ この部分をインクルード処理したい ▼▼
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="keywords" content="">
<link rel="stylesheet" href="style.css">
// ▲▲ ここまで ▲▲
    <body>
        <h1><?= $player . 'のメニュー' ?></h1>
        <p><a href='walk.php'>あるく</a></p>
        <p><a href='attack.php'>たたかう</a></p>
    </body>
</html>

①別ファイルに保存
通化したい部分を適当なファイルに別保存

②呼び出す
で呼び出す。 以上

<?php include('header.inc.php'); ?>
    <body>
        <h1><?= $player . 'のメニュー' ?></h1>
        <p><a href='walk.php'>あるく</a></p>
        <p><a href='attack.php'>たたかう</a></p>
    </body>
</html>

【テンプレート】処理と見た目を分ける方法

タイトルが少しわかりにくいがhtmlデータのレスポンスには2通りある。

■静的データ
サーバに整形されたhtmlデータがありそれをレスポンスで返す。

■動的データ
phpを使い、ユーザーからのリクエストによってレスポンスするhtmlのデータをサーバー上で整形してからレスポンスしている。

ロジック

・ざっくりいうと、htmlデータの整形には、【A】phpでデータを扱うファイル【B】WEBデータを見た目をhtmlで整えるファイルが分かれており、URLで【A】にアクセスしたとき【A】のファイルが【B】のファイルを読み込み、【B】のファイルをレスポンスするという仕組みである。
※もちろんこの時、【A】ファイル内の変数や配列などのよって【B】内のhtml内の記述を少し作り直しているのだ。

f:id:aruku-hito:20191120214306p:plain

require_once関数

青が緑を読み込むために、青ファイルにrequire_onceを記述する。
自動的に緑ファイルを読み込む(=見た目のファイルを返している)

【青ファイル】

<?php
$message = "プレイヤーは戦った!";
$enemys = ['スライム','ドラゴン','ゾンビ','ゴブリン'];

require_once 'attack.tpl.php'; 
?>

【緑ファイル】
こちらは見た目ファイル。青ファイルにある変数や配列データは使えるのでところどころにphpがある。

<!DOCTYPE html>
<html lang='ja'>
    <body>
        <h1>戦いの結果</h1>
        <p><?= $message ?></p>
        <?php foreach($enemys as $enemy) {  ?>
     <p><?= $enemy ?> . 'を倒した!'</p>
        <?php }  ?>
        <p><a href='menu.php'>戻る</a></p>
    </body>
</html>


【レスポンス】
プレイヤーは戦った!
ドラゴンを倒した!
'ゾンビを倒した!
ゴブリンを倒した!