Skip to content

Instantly share code, notes, and snippets.

@simics-ja
Last active January 21, 2019 08:52
Show Gist options
  • Save simics-ja/7cc42aca7e062eef5fa26ce796240700 to your computer and use it in GitHub Desktop.
Save simics-ja/7cc42aca7e062eef5fa26ce796240700 to your computer and use it in GitHub Desktop.
[PDOメモ] #php #mysql

PHPでMySQLを操作しよう.

<?php
define('DB_DATABASE', 'MySQLDB');
define('DB_USERNAME', 'dbuser');
define('DB_PASSWORD', 'password');
define('PDO_DSN', 'mysql:dbhost=localhost;dbname=' . DB_DATABASE);
<?php
try {
//connect
$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//insert
$db->exec("insert into users (name, score) values ('hoge', 55)");
echo 'inserted:' . $db->lastinsertId(); #最後に挿入されたレコードのIDを表示
//disconnect
$db = null;
} catch(PDOException $e) {
echo $e->getMessage();
exit;
}

PDOで使えるメソッド

  • exec() 結果を返さない.安全なSQLの実行に向いている.
  • query() 結果を返す.安全なSQL & 何回も実行されないものに向いている.
  • prepare() 結果を返す.安全対策が必要.何回も実行される(=再利用できる)SQLに向いている.
<?php
//connect
$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $db->prepare("insert into users (name, score) values (?, ?)");
$stmt->execute(['hoge', 55]);
//名前付きパラメータを使う場合
$stmt = $db->prepare("insert into users (name, score) values (:name, :score)");
$stmt->execute([':name'=>'foo', ':score'=>80]);

bindValue

nameがhogeに対して複数のscoreを割り当てるのにbindValueが便利 一部が異なる複数のデータをループ等を用いれば挿入できる.

<?php
$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $db->prepare("insert into users (name, score) values (?, ?)");
// bindValue(何番目の?か, 値, データの型)
// 第一引数は名前付きパラメータであってもそのまま使える..
// 例:bindValue(':name', $name, PDO:PARAM_STR)
$name ='hoge';
$stmt->bindValue(1, $name, PDO:PARAM_STR);
$score = 70;
$stmt->bindValue(2, $score, PDO:PARAM_INT);
$score = 40;
$stmt->bindValue(2, $score, PDO:PARAM_INT);
$stmt->execute();
// execute()は引数がなければbindされた値で実行される.
// ['hoge', 70]と['hoge', 40]が挿入される.
// bindValuの第三引数他にもいろいろ
// PDO::PARAM_NULL
// PDO::PARAM_BOOL

bindParam

bindValueは値と?(or 名前付きパラメータ)を結びつける. bindParamは値の参照先と?(or 名前付きパラメータ)を結びつける.

<?php
$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $db->prepare("insert into users (name, score) values (?, ?)");
$name ='hoge';
$stmt->bindValue(1, $name, PDO:PARAM_STR);
$stmt->bindParam(2, $score, PDO:PARAM_INT); #これ以降2番目の?は$scoreを参照し続ける.
$score = 70;
$stmt->execute();
$score = 40;
$stmt->execute();
<?php
$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $db->query("select * from users");
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($users as $user){
var_dump($user);
}
echo $stmt->rowCount() . 'records found.';
<?php
$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// scoreが60以上の人
$stmt = $db->prepare("select score from users where score > ?");
$stmt->execute([60]);
// nameにtを含む人
$stmt = $db->prepare("select name from users where name like ?");
$stmt->execute(['%t%']);
// soreが最上位の1名
$stmt = $db->prepare("select name from users order by score desc limit ?");
$stmt->bindValue(1, 1, PDO::PARAM_INT);
// $stmt->execute([1]);ではうまくいかない.execute()の引数は全て文字列で渡されるが,limitは数値で渡す必要がある.

PDO::FETCH_CLASSとは

FETCH_CLASSを使うと抽出した結果を指定したクラスに直接セットできる.

<?php
class user{
/*
public $id;
public $name;
public $score;
実はFETCH_CLASSは自動的にカラムをクラスのpublicに設定してくれるのでここでは省略可能
*/
public function show(){
echo "$this->name ($this->score)";
}
}
try {
//connect
$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $db->query("select * from users");
$users = $stmt->fetchAll(PDO::FETCH_CLASS, 'User');
foreach($users as $user){
$user->show();
}
}catch (PDOException $e){
$e->getMessage();
}
<?php
$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//更新処理
$stmt = $db->prepare("update users set score = :score where name = :name");
$stmt = excecute([
':score' => 100,
':name' => 'hoge'
])
echo "row updated:" . stmt->rowCount();
//削除処理
$stmt = $db->prepare("delete from users where name = :name");
$stmt = excecute([
':name' => 'heshitaihito'
])
echo "row deleted:" . stmt->rowCount();

下記の例ではユーザfooからbarにスコアを10渡す. つまりfooから10引いて,barに10を足す. ただし,何らかの原因で処理がうまくいかなかったとき,点数をもとに戻す必要がある. 銀行の取引とかはそのへんをうまくやらないといけない. それを実現するのがトランザクション.

<?php
try{
$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//transaction
$db->beginTransaction();
$db->exec("update users set score = score - 10 where name = 'foo'");
$db->exec("update users set score = score + 10 where name = 'bar'");
$db->commit();
} catch (PDOException $e){
$db->rollback(); //トランザクションをするなら必須なので注意.トランザクション中でエラーが発生したとき,トランザクション前にデータを戻す命令.
$e->getMessage();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment