taitokissの備忘録

調べたことを忘れないように書き留めています。

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」。次の記事にまとめます。