12,964
回編集
(→SELECT) |
|||
520行目: | 520行目: | ||
<br><br> | <br><br> | ||
== | == プリペアドステートメント == | ||
プリペアドステートメントとは、実行するSQLをコンパイルしたテンプレートのようなものである。<br> | プリペアドステートメントとは、実行するSQLをコンパイルしたテンプレートのようなものである。<br> | ||
パラメータ変数を使用することで、SQLをカスタマイズすることができる。<br> | パラメータ変数を使用することで、SQLをカスタマイズすることができる。<br> | ||
529行目: | 529行目: | ||
<br> | <br> | ||
プリペアドステートメントは、データベースの種類や機能に関わらず同じ仕組みで データベースへのアクセスができる。<br> | プリペアドステートメントは、データベースの種類や機能に関わらず同じ仕組みで データベースへのアクセスができる。<br> | ||
<br><br> | |||
== レコードの取得(プリペアドステートメント) == | |||
==== PDOStatement::fetchメソッド ==== | |||
カーソルを移動して、指定したフェッチモードで1行ずつ取得する。<br> | |||
* 引数を省略する場合、デフォルトフェッチモードが使用される。 | |||
* 全てのレコードを取得した場合、falseを返す。 | |||
<br> | <br> | ||
以下の例では、フェッチモードを<code>PDO::FETCH_ASSOC</code>に設定している。<br> | |||
<syntaxhighlight lang="php"> | <syntaxhighlight lang="php"> | ||
// 基本的な構文 | |||
while($row = $stmt->fetch()) | |||
$ | { | ||
printf("%s lives in %s<br />\n", $row['name'], $row['city']); | |||
} | |||
// vprintf関数を使用する場合 | |||
while($row = $stmt->fetch()) | |||
$ | { | ||
vprintf("%s lives in %s<br />\n", $row); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
デフォルトフェッチモードの場合、<code>PDOStatement</code>クラスは<code>Traversable</code>インターフェースを実装しているため、foreach文で記述することができる。<br> | |||
ただし、HTMLのための変数を用意する場合、配列として持つ方が都合が良いため、<code>PDOStatement::fetchAll</code>メソッドの使用することを推奨する。<br> | |||
<syntaxhighlight lang="php"> | |||
foreach($stmt as $row) | |||
{ | |||
printf("%s lives in %s<br />\n", $row['name'], $row['city']); | |||
} | |||
// 0から始まるオフセットを取得することもできる | |||
$name | foreach($stmt as $i => $row) | ||
$value = | { | ||
printf("[%d] %s lives in %s<br />\n", $i, $row['name'], $row['city']); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== PDOStatement::fetchObjectメソッド ==== | |||
連想配列の代わりにクラスオブジェクトを取得する。<br> | |||
これは、<code>PDO::FETCH_OBJ</code>を指定して<code>PDOStatement::fetch</code>メソッドを使用する場合と同じであるが、こちらの方が簡潔に記述できる。<br> | |||
<syntaxhighlight lang="php"> | |||
while($row = $stmt->fetchObject()) | |||
{ | |||
printf("%s lives in %s<br />\n", $row->name, $row->city); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== PDOStatement::fetchColumnメソッド ==== | |||
特定の1カラムのみを文字列として取得する。<br> | |||
これは、<code>PDO::FETCH_COLUMN</code>を指定して<code>PDOStatement::fetch</code>メソッドを使用する場合と同じでるが、こちらの方が簡潔に記述できる。<br> | |||
<br> | |||
先頭から数えてそのカラムが何番目(0オリジン)にあるかを第1引数として渡す。(省略する場合、0を指定したとみなされる)<br> | |||
カラムの値に0が含まれる可能性がある場合は、<code>false !==</code>の判定をしなければならない。<br> | |||
<syntaxhighlight lang="php"> | |||
while(false !== $value = $stmt->fetchColumn()) | |||
{ | |||
echo "{$value}<br />\n"; | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
==== | ==== PDOStatement::fetchAllメソッド ==== | ||
全てのレコードを取得して2次元配列とする。<br> | |||
* 引数を省略する場合、デフォルトフェッチモードが使用される。 | |||
* 特定のカラムのみ全てのレコードを取得して1次元配列とする場合、<br>第1引数に<code>PDO::FETCH_COLUMN</code>を指定して、第2引数に先頭から数えてそのカラムが何番目(0オリジン)にあるかを渡す。(省略する場合、0を指定したとみなされる) | |||
<syntaxhighlight lang="php"> | <syntaxhighlight lang="php"> | ||
$rows = $stmt->fetchAll(); | |||
var_dump($rows); | |||
$values = $stmt->fetchAll(PDO::FETCH_COLUMN); | |||
var_dump($values); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
以下の例では、フォームで入力したキーの値に応じたデータを取得している。<br> | 以下の例では、フォームで入力したキーの値に応じたデータを取得している。<br> | ||
ユーザの入力内容は自動的に引用符で括られるため、SQLインジェクション攻撃の恐れは無い。<br> | ユーザの入力内容は自動的に引用符で括られるため、SQLインジェクション攻撃の恐れは無い。<br> | ||
631行目: | 662行目: | ||
また、PDO::ATTR_STRINGIFY_FETCHESオプションをtrueに指定する時、エミュレーションが無効の場合は数値が文字列に変換される。<br> | また、PDO::ATTR_STRINGIFY_FETCHESオプションをtrueに指定する時、エミュレーションが無効の場合は数値が文字列に変換される。<br> | ||
エミュレーションが有効の場合、設定に関わらず常に数値が文字列に変換される。<br> | エミュレーションが有効の場合、設定に関わらず常に数値が文字列に変換される。<br> | ||
<br><br> | |||
== レコードの追加(プリペアドステートメント) == | |||
以下の例では、nameおよびvalueを<u>名前付きプレースホルダ</u>で置き換えて、INSERT文を実行している。<br> | |||
<syntaxhighlight lang="php"> | |||
<?php | |||
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)"); | |||
$stmt->bindParam(':name', $name); | |||
$stmt->bindParam(':value', $value); | |||
// 1レコード目の挿入 | |||
$name = 'one'; | |||
$value = 1; | |||
$stmt->execute(); | |||
// パラメータを変更して、2レコード目の挿入 | |||
$name = 'two'; | |||
$value = 2; | |||
$stmt->execute(); | |||
?> | |||
</syntaxhighlight> | |||
<br> | <br> | ||
以下の例では、nameおよびvalueを<u>プレースホルダ<code>?</code></u>で置き換えて、INSERT文を実行している。<br> | |||
<syntaxhighlight lang="php"> | |||
<?php | |||
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)"); | |||
$stmt->bindParam(1, $name); | |||
$stmt->bindParam(2, $value); | |||
// 1レコード目の挿入 | |||
$name = 'one'; | |||
$value = 1; | |||
$stmt->execute(); | |||
// パラメータを変更して、2レコード目の挿入 | |||
$name = 'two'; | |||
$value = 2; | |||
$stmt->execute(); | |||
?> | |||
</syntaxhighlight> | |||
<br><br> | |||
== ストアドプロシージャ == | |||
==== ストアドプロシージャの呼び出し : 出力パラメータの指定 ==== | ==== ストアドプロシージャの呼び出し : 出力パラメータの指定 ==== | ||
データベースドライバがサポートしている時、入力パラメータだけでなく、出力パラメータもバインドすることが可能である。<br> | データベースドライバがサポートしている時、入力パラメータだけでなく、出力パラメータもバインドすることが可能である。<br> | ||
669行目: | 741行目: | ||
?> | ?> | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br><br> | ||
== プレースホルダの間違った使用例 == | |||
<syntaxhighlight lang="php"> | <syntaxhighlight lang="php"> | ||
<?php | <?php |