PHPのODBC関数を使うときの注意点

PHPODBC関数でプリペアードステートメントを使うには
odbc_prepare, odbc_executeの2つの関数を使います。

例1

<?php
$a = 1;
$b = 2;
$c = 3;
$stmt    = odbc_prepare($conn, 'CALL myproc(?,?,?)');
$success = odbc_execute($stmt, array($a, $b, $c));

odbc_executeの第2引数にはパラメータの配列($parameters_array)を渡す。

ただし、次のような注意点がある。

parameter_array の中でシングルクォートで括られたデータがある場合、 それはファイル名と解釈されます。そのファイルの内容が、 該当するプレースホルダのデータとしてデータベースサーバに送信されます。


だから

シングルクォートで括られたデータを純粋に文字列として使用したい場合は、 空白などの別の文字を前後に付加する必要があります。 それにより、パラメータがファイル名とみなされることがなくなります (もしこのオプションが不要なら、別の仕組み、たとえば odbc_exec() で直接クエリを実行するなどを使用する必要があります)。

つまり、「''でくくられた文字列をファイル名とみなす」という特例を必要としない場合*1例1のコードはそのままの形で使用することはできない。
次のような「'で始まり'で終わる文字列の末尾に空白を付ける関数」なりなんなりでパラメータをエスケープしなければならない。


例2

<?php
function odbc_escape_params ($params) {
 if (!is_array($params) or empty($params)) {
  return array();
 }
 foreach ($params as $key=>$val) {
  if (strlen($val) > 1 and $val{0} == "'" and $val{strlen($val)-1} == "'") {
   $params[$key] .= ' ';
  }
 }
 return $params;
}

これでとりあえずしのげはするが、''でくくられた文字列をそのままの形でDBに収めることは結局できてないわけだ。。。はあ。。。



参考・引用元: PHPマニュアル
http://www.php.net/manual/ja/function.odbc-execute.php

*1:ほとんどの人はそうだろう