PHPでデータベースを使う。
今回はdotinstallのPHPデータベース入門の#1~#13について。
PDO=PHP Data Objectの略
拡張モジュールの一種で、PHPの中からデータベースに接続する
PDOを使う際の注意
PHP7にはSQLiteがデフォルトで有効になっているのでMySQLを有効にする。
php-mysqlndとphp-fpmをインストールする(どちらもPHPインストールの時に一緒にインストールすると便利)
個別にインストールする場合は、php-fpmのインストール後に
systemctl restart httpd.serviceで再起動させると有効になる
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
まず、データベースの設定(mysql側で)をする。
・端末で$ mysql -u root -pでルート権限に接続
・mysql> create database ~
→データベースの作成(例 MenuList)
・mysql> grant all on ~
→作成したデータベースに限って全権限を与えたユーザの作成
identified by でパスワードを付与しておく
(例 ユーザ名をchief01, パスワードをGG09F77)
・create table ~
→テーブルを作成。1つ以上の値などを指定しないとエラーになる。
例
× create table menu;
○ create table menu(id int auto_increment primary key,name varchar(255),
price int);
・一度quit; or \qでルート権限を抜ける
・端末で$ mysql -u chief01 -p menuListと入力
→chief01のユーザ名でmenuListというデータベースに接続する。
・show tables
→テーブルの確認
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
次にPHP側でPDOを設定する。
(mysqlの操作画面を抜けてから)
・PHPのファイルを作成
→vagrantで仮想マシンに接続しているので、その端末から操作する。
その場合、webサイトで確認したい内容であれば、ドキュメントルート
/var/www/html(CentOSの場合)の直下にphpファイルを保存する。
cd /var/www/htmlでディレクトリを移動
vim pricelist.phpなどとしてPHPファイルを作成
新しいファイル(pricelist.php)が編集可能になるので、それを編集する。
・define文でデータベースを定義する
defineは定数を定義する際に使う。
difine('DB_DATABASE', 'menuList');
→ データベースmenuListをDB_DATABASEに格納
define('DB_USERNAME', 'chief01');
→ ユーザ名をDB_USERNAMEに格納
define('DB_PASSWORD, 'GG09F77');
→パスワードをDB_PASSWORDに格納
define('PDO_DSN', 'mysql:host=localhost;dbname=' .DB_DATABASE');
→PDO_DSNはデータベースに接続する情報が含まれたもの
DataSourceNameの略
DSNは各PDOドライバ(mySQLやSQLite,PostgreSQLなどのSQL)
の後にコロンが続き、そのあとに固有の接続構文が入る。
hostのアドレスなどを入れる場合がある。
・defineで定数の定義を終えたらtry→catchでエラーモードの指定と例外処理の指定をする。
try{
$db = new(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$db = setAttribute(PDO:ATTR_ERRMODE,
PDO::ERRMODE_EXCEPTION);
→setAttributeで属性を設定、エラーモードをATTR_ERRMODE(エラーをレポートする)、ERRMODE_EXCEPTION(例外を投げる)というように設定する。
}catch(PDOExeption $e){
echo $e->getMessage();
exit;
}
→ 受け取った例外メッセージを出力する。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
exec()→これは結果を返す必要がない
query()→結果を返すが一回の関数コールのみで得られた結果セットを返す
prepare()→結果を返し、複数回の実行をする、安全対策が必要
ユーザからの入力に対して悪意のあるコードに対する対策を行う
statmentオブジェクト(容器の役目をする)が返ってくる。
このオブジェクトにはexecute()というメソッドがあり、
そちらに受け渡すと安全な形で値を埋め込むことができる
lastInserted()→最後に挿入したレコードのIDを引っ張ってくる関数
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
名前付きパラメータ
prepareに対して名前付きパラメータを設定できる
$stmt = prepare("inser into テーブル名(name, score) values (:name, :score);
$stmt ->execute([':name'=>'tanaka', ':score'=>65]);
パラメータの定義には2種類ある
(?, ?)→valuesの後の()内に?を入れる、使いやすくてシンプル
(:変数1, :変数2)→()内に:に続いて値を入れたい変数を入れる
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
bindValueとbindParam
bindValueは値を紐づけする関数
bindParamはパラメータを紐づけし、変数も参照として紐づけしてexecute()が実行されたときにそのパラメータを評価する。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
query()での抽出 query→結果は返すが一回の実行のみの関数
$stmt = $db->query("select from user");というように指定
fetchall → 全ての結果行を含む配列を返す
fetch_assoc→帰ってきた値のカラム名で添え字をつけた配列を返す
fetchallで抽出する文にはforeachが使える
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
条件付きでの抽出 prepare()を使う
$stmt = prepare(指定文)→抽出したい部分を?にする(数字の抽出)
execute([?の中身を挿入]);
文字の抽出も同じようにできる
スコアを降順に並べて上位1位の数字を取り出す
$stmt = prepare("select score from テーブル名 order by score desc limit ?")
これはこのままexecuteするとエラーになる(解釈がうまくいかない)
bindValueで紐づけする
$stmt->bindValue(1,1, PDO::PARAM_INT)
$stmt->execute();
で文の解釈がうまくいく
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
FETCH CLASS
抽出したデータを任意のクラスに直接セットする
class User(){
public function show(){echo "$this->name($this->score));
}
}
$stmt = $db->query("select * from テーブル名);
$テーブル名 = $stmt->fetchAll(PDO::FETCH_CLASS, 'User');
省いているところがあるが、query関数で呼び出した結果を$stmtに代入し、
それをテーブルの中に代入するという式
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
更新と削除
特定の名前に対してスコアを更新する
$stmt = $db->prepare("update テーブル名 set score = :score where name = :name);
$stmt->execute([':score'=>100, ':name'=>'tanaka']);
特定の名前を削除する
$stmt = $db->prepare("delete from テーブル名 name = :name);
$stmt->execute([':name'=>'satou']);
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
ある処理を行う際にその処理が必ず行われることを保証する
処理の前に
$db->beginTransaction();
としてその続きに処理を書く
処理の記述の後に$db->commit(正しければ反映する)と記述
また、例外処理のところにもし処理を間違えても元に戻したいという記述をする場合
$db = rollback();
と記述する
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
〇まとめ
PHPとデータベースを関連付けて操作する方法についてはだいぶ理解ができたので、
あとは実際に0から作ってみたときにどこにつまずくのかをしっかりと把握しておきたい。関数とオブジェクトのあたりでどの関数を使うかを迷いそうな気もするのできちんと復習しておく。