2016年12月27日火曜日

MySQLとPHP/基本のメモ2

続きです。


メモ

ユーザ一覧表示
> SELECT user, host FROM mysql.user;
前回も載せたんですけどね。覚えてなかったので。
mysqlというシステム用のスキーマがあり、そこにuserテーブルがあると。

ユーザの削除
> drop user dbuser@localhost;

PHP Data Objects(PDO)
PHPでDBへつなぐ時のインターフェース。コネクターのことかな。

変数名の_アンダースコア
人気があるコーディング規約
プロパティの変数名の頭に_をつけることで、thisをつけなくても(つけ忘れても)
プロパティとわかりやすくする。また、そうすることで変数名の重複を減らすことができる。

ヒアドキュメント内の変数
展開される
シェルスクリプトとはちがうみたい

define('key' , 'value);
定数の設定。Javaと違いすぎて忘れる。

PDOのテンプレ
まず、DB名やユーザ名・PWを定数定義するとして、
try {
  // connect
  $db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  // proc
  $db->exec("insert into users (name,score) values ('hoge', 5);");
  echo "user added!";


} catch (PDOException $e) {
  echo $e->getMessage();
  exit;
}

error
SQLSTATE[42000]: Syntax error or access violation: 
1064 You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version 
for the right syntax to use near 
'insert555 into users (name,score) values ('tag', 5)' at line 1

preppare()
複数回使うクエリに適している。SQLインジェクションの対策が必要。
  $stmt = $db->prepare("insert into users ( name , score ) values ( ? , ? );");
  $stmt->execute(['hoge', 100]);
  echo "insert no : " . $db->lastInsertId();

exec()
結果を返さないで実行する。selectなど。
安全なクエリに使う。

query()
結果を返す。
安全、かつ、一度しか実行されないようなクエリに使う。
下記の例は2次元配列として格納されるようです。(3つの要素を持つ連想配列の配列)
  $stmt = $db->query("select * from users");
  $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
query()の結果は、PDOStatement オブジェクトが返ります。 詳しいことはQiitaのこの記事を読んでください。

$db->lastInsertId();
最後に挿入されたレコードのIDを返します。

名前付きパラメータ
「:パラメータ名」とすることで連想配列みたいに扱える。
  $stmt = $db->prepare("insert into users ( name , score ) values ( :name , :score );");
  $stmt->execute([':name'=>'hoge', 'score'=>100]);
:を付けても付けなくてもアクセスできました

bindValue()
プレースホルダーに値を保持させたままにすることができる。
下記の例だと$nameは変えてないので、hogeでちがうscoreのレコードを2行挿入できる。
  $stmt = $db->prepare("insert into users ( name , score ) values ( ? , ? );");

  $name = 'hoge';
  $stmt->bindValue(1, $name, PDO::PARAM_STR);
  $score = 43;
  $stmt->bindValue(2, $score, PDO::PARAM_INT);
  $stmt->execute(); // 1st
  $score = 55;
  $stmt->bindValue(2, $score, PDO::PARAM_INT);
  $stmt->execute(); // 2nd


プレースホルダーに名前を付けるとこうなる。
  $stmt = $db->prepare("insert into users ( name , score ) values ( :name , :score );");

  $name = 'hoge';
  $stmt->bindValue('name', $name, PDO::PARAM_STR);
  $score = 43;
  $stmt->bindValue('score', $score, PDO::PARAM_INT);
  $stmt->execute(); // 1st
  $score = 55;
  $stmt->bindValue('score', $score, PDO::PARAM_INT);
  $stmt->execute(); // 2nd

その他のデータ型
PDO::PARAM_NULL
PDO::PARAM_BOOL

bindParam();
プレースホルダーが参照する変数を固定する
  $stmt = $db->prepare("insert into users ( name , score ) values ( :name , :score );");

  $name = 'hoge';
  $stmt->bindValue('name', $name, PDO::PARAM_STR);

  $stmt->bindParam('score', $score, PDO::PARAM_INT);
  $score = 100;
  $stmt->execute();
  $score = 400;
  $stmt->execute();

FETCH_CLASS
PDOオブジェクトをクラスに代入する
Userクラスを作った上で、FETCH_CLASSするとオブジェクトを配列で返す。
class User {
# public $id;
# public $name;
# public $score;
  public function show() {
    echo "$this->name ($this->score) <br>\n";
  }
}

  $stmt = $db->query("select * from users");
  $users = $stmt->fetchAll(PDO::FETCH_CLASS, 'User');
プロパティは書かなくても、PDOのフィールドが勝手に保持されるみたいです。
楽だけどバグに気づかなそうなので、明示すべきですかね。

$stmt->rowCount()
PDOオブジェクトが持つ行数(要素数)を返す。

$db-beginTransaction();
トランザクション開始

$db->commit();
トランザクション終了

$db->rollback();
ロールバック
PDOExceptionをキャッチさせて使う。

0 件のコメント:

コメントを投稿