PHPでMySQLデータベースに接続する (mysqli オブジェクト型 編)
先の記事では、mysql・mysqli 手続き型を用いたMySQLデータベースへの接続方法を書いた。しかし、手続き型での処理は過去のものとなりつつあり、既にPHP7では mysql 系のサポートは終了している。
ここからは、本命となる mysqli・PDO オブジェクト指向型での扱い方を書いていく。
1.用意しておくデータベース
前編でも書いているが、見返すのも何なのでテストに使用する MySQLデータベースを書いておく。
データベース名:uriage
ユーザー名:testuser
パスワード:testuser
テーブル名:shouhin
テーブル構成:
id name
1 テレビ
2 DVD
3 パソコン
4 プリンタ
5 HDD
6 ラジオ
の内容でデータベースが用意されているものとする。
2.mysqli オブジェクト指向型での処理
まずは、シンプルなサンプルから。
mysqli_系 データベースへの接続サンプル5(オブジェクト型)
4行目 $mysqli = new mysqli(host, username, passwd, dbname)
コンストラクタを呼び出し、mysqliクラスのオブジェクトを作成する。
5行目 $mysqli -> connect_error
エラーの内容を表す文字列を返す。エラーが発生しなかった場合は NULL を返す。
10行目 $mysqli -> set_charset(charset)
データベースサーバーとのデータの送受信に使用する、 デフォルトの文字セットを設定する。文字化け防止として入れておく。
成功した場合に TRUE を、失敗した場合に FALSE を返す。
13行目 $mysqli -> query(query)
データベースに対して query(SQL文) を実行する。
失敗した場合に FALSE を返す。SELECT, SHOW, DESCRIBE, EXPLAIN が成功した場合、mysqli_resultオブジェクトを返す。それ以外のクエリが成功した場合、TRUE を返す。
16行目 $result -> fetch_assoc()
取得した行に対応する文字列の連想配列を返す。連想配列の各キーが、結果セットのカラムを表す。結果セットにもう行がない場合には NULL を返す。
22行目 $result -> free()
結果に関連付けられたメモリを開放する。返り値は無し。
26行目 $mysqli -> close()
事前にオープンしているデータベース接続を閉じる。
成功した場合に TRUE を、失敗した場合に FALSE を返す。
基本的には手続き型と同様の流れだが、 簡潔で短くなるので書きやすいかな?
3.プリペアドステートメントを使う
上の「データベースへの接続サンプル5(オブジェクト型)」13行目の
$result = $mysqli->query("SELECT id, name FROM shouhin WHERE id > 2 AND id < 5"
のように、完成済みのSELECT文を実行する場合などは、SQLインジェクションを心配しなくていいようだが、検索条件を固定して問い合わせることはまずないだろう。 実際には、SQL文に検索条件を外部から渡しクエリーを実行するという事になる。この時にSQLインジェクションを招く結果となる。
それを防止する対策として、手続き型でも例を示したように、プリペアドステートメントを用いる。次にそのサンプルを書いておく。
mysqli_系 データベースへの接続サンプル6(オブジェクト型でプリペアドステートメントを使う
13行目 $sql = "SELECT id, name FROM shouhin WHERE id > ? AND id < ?"
「?(パラメータマーカ)」を含んだSQLクエリを準備する。
16行目 $stmt = $mysqli->prepare($sql)
SQL クエリを準備し、後でそのステートメントを操作するために使用するステートメントハンドルを返す。クエリは、単一のSQL 文である必要がある。
「?(パラメータマーカ)」は、ステートメントの実行や行の取得の前に変数にバインドする必要がある。
ステートメントオブジェクトを返す。エラー時には FALSE を返す。
18行目 $id1 = 2; $id2 = 5
$stmt->bind_param("ii", 2, 5) のように、値を引数内に直書きできないので予め「?(パラメータマーカ)」にセットする条件値を変数にセットしておく。
21行目 $stmt->bind_param("ii", $id1, $id2)
変数を SQLステートメントのパラメータマーカにバインドする。
「”ii”」で、$id1, $id2の順にパラメータの型を指定している。
以下の指定ができる。
i :Integer
d:double
s:string
b:blob
24行目 $stmt->execute()
プリペアドクエリを実行する。パラメータマーカが存在する場合、その内容は自動的に適切なデータに置き換えられる。
ステートメントが UPDATE、DELETE あるいは INSERT であった場合、変更された行の総数は stmt->affected_rows を使用することで取得可能。同様に、クエリが結果セットを返す場合は stmt->fetch() を使用できる。
このメソッドを使用した場合、他のクエリを実行する前に stmt->fetch() を使用する必要がある。
成功した場合に TRUE を、失敗した場合に FALSE を返す。
27行目 $stmt->bind_result($id, $name)
mysqli_stmt::bind_result( var1, var2, ... )
結果を保存するため、プリペアドステートメントに変数をバインドする。
データを取得するために mysqli_stmt::fetch() がコールされた場合、MySQL クライアント/ サーバー プロトコルはバインドされたカラムのデータを var1, ... に格納する。
PHP manualには、全てのカラムを、mysqli_stmt_execute() をコールしてから mysqli_stmt_fetch() をコールするまでの間に バインドしておく必要があることに注意しましょう。カラムの型に 応じて、バインド変数の型も対応する PHP の型に自動的に変換されます。
カラムのバインドや再バインドはいつでも可能で、たとえ結果セットを途中まで 取得した後であっても可能です。新しくバインドした内容が効力を発揮するのは、 次に mysqli_stmt_fetch() がコールされたときからです。
とあるが、オブジェクト型でも同様 だろうな?
手続き型を例として書いてあると思うが、「オブジェクト型でも同様」との注意書きをしてほしかった。何しろ、初心者なもので手取り足取りでないと不安なので。
30行目 $stmt->fetch()
プリペアドステートメントから結果を取得し、バインド変数に格納する。
35行目 $stmt->close()
プリペアドステートメントを閉じる。
stmt が指すステートメントハンドルを開放します。 現在のステートメントが実行中あるいはまだ結果を取得していない場合、 このメソッドはキャンセルされ、次のクエリが実行される。
成功した場合に TRUE を、失敗した場合に FALSE を返す。
こんな感じかな?
最後は、「PDO」。次の記事にまとめます。