Windows Server 2008上のphp5.5でOracle 11gを扱うという今が2018年か疑わしくなるような環境で開発をしたのですが、その際にoci_bind_by_nameに関するトラブルがあったので記述しておきます。
このプロジェクトは、Webから入力される情報を登録することになりますので、DBに登録するSQLの作成にはプレースホルダを使うことにしました。
当初のプログラムは次のようになります。
foreach($columns as $name => $value){ oci_bind_by_name($stid, ":" . $name . '_bv', $value); }
$columns連想配列にセットされているのはカラム名と値です。
これで生成されたSQLを実行すると、次のようなエラーが表示されました。
ORA-01461: LONG値はLONG列にのみバインドできます。
LONGってでかい整数のはずなので、そんなのセットしていないのにな・・・とさんざん悩みました。
いろいろコーディングを試したところ、次のように書くとエラーが発生しないことが分かりました。
oci_bind_by_name($stid, ':name_bv', $columns['name']);
foreachで回すと駄目なのに、直接配列をしていすればうまくいくのです。
怪しい点に気づいたのは oci_bind_by_name のマニュアルページを調べたときでした。
第三引数が参照型になっているんですよね。
仮説ですが、foreachでセットされる$valueはポインター的な値が入っており、それがoci_bind_by_nameで使われてしまうのではないのかと考えました。
そこでコーディングを下記のようにしました。
foreach($columns as $name => $value){ oci_bind_by_name($stid, ":" . $name . '_bv', $columns[$name]); }
これならLong値のエラーが発生すること無く動作するようになりました。
釈然とはしませんが、動いてよかったです!