|
|
前のページ 1 2 3 次のページ
|
|
独自のエスケープ機能を呼び出す際の注意点
|
しかし、データベース独自のエスケープ機能を呼び出す前にマジッククォートの状態を確認することが大切です。マジッククォートが有効になっている場合、付け加えられたバックスラッシュ()をすべて取り除く必要があります。そうしないとユーザの入力はすでにエスケープされているので、二重にエスケープされてしまうことになり、エスケープ記号の意味がなくなってしまうのです。
入力の安全性確保に加え、データベース特有のエスケープ関数はデータ破壊を防ぎます。例えば、MySQL拡張機能のエスケープ関数は、マルチバイト文字を認識してエンコードすることで、データが破壊されないことを保障します。
ネイティブなエスケープ関数はバイナリデータの保存に対しても無意味になります。'エスケープ'しない場合は除きますが、バイナリデータはデータベース自体のストレージフォーマットと衝突する場合があって、これはテーブルやデータベース全体の破壊や喪失の原因となります。
PostgreSQLのように、データベースの中にはバイナリデータをエンコードする専用の関数を提供しているものもあります。問題を起こす可能性のある文字をエスケープする機能に加え、このような関数は内部的にエンコードを適用します。例えば、PostgreSQLのpg_escape_bytea()関数はバイナリデータにBase64のようなエンコードを適用します。
|
// プレーンテキスト型のデータを使用する場合:
pg_escape_string($regular_strings);
// バイナリデータを使用する場合:
pg_escape_bytea($binary_data);
|
バイナリデータをエスケープする仕組みは、データベースが本来サポートしていないマルチバイト言語を処理するのにも利用されます。(日本語のようなマルチバイト言語は1文字をあらわすのに複数のバイトを使います。これらの中には普通ならバイナリデータにしか使われないASCII の領域とかぶるものもあります。)
バイナリデータのエンコードには欠点があります。データが完全一致以外の検索が行えないようにしてしまうのです。言い換えれば、LIKE'foo%'のような部分一致検索が使えない、ということです。これは、データベースに保存されているエンコードされた値が、必ずしも部分一致で指定した文字列にエンコードされているとは限らないためです。
しかしアプリケーションのほとんどで、この制限は大きな問題にはなりません。というのは、部分検索は一般的に人が読んでわかるデータに対して行われ、イメージや圧縮ファイルのようなバイナリデータには行われないからです。
|
プリペアードステートメント
|
データベース特有のエスケープ関数は役に立つものですが、すべてのデータベースでこのような機能が提供されているわけではありません。実際、データベース固有のエスケープ関数があるデータベースは比較的少数です。(この記事作成時は)MySQL、PostgreSQL、SQLite、Sybase、MaxDB の拡張機能でしか提供されていません。Oracle、Microsoft SQL Serverなどを含むその他のデータベースでは、別の解決策が必要になります。
一番よく使われるテクニックが、データベースに入るデータをすべてBase64でエンコードするというもので、こうすることでどんな特殊な文字があっても蓄えられているデータが破壊されるなどのトラブルを防げます。しかしBase64エンコードを行うと約33%データ量が増えるので、より大容量のカラムやストレージが必要になります。
さらに、Base64でエンコードされたデータにはPostgreSQLでのバイナリエンコードデータと同様の問題があります。LIKE を使った検索ができないのです。従って、入ってくるデータがクエリの構文に影響を与えないような、よりよい解決策が必要となります。
|
前のページ 1 2 3 次のページ
|
|
|
|
著者プロフィール
Ilia Alshanetsky
PHP開発チームの活動メンバーの1人であり、現在のPHP 4.3.X.のリリースマネージャー。また、オープンソース掲示板FUDフォーラム(http://fud.prohost.org/forum/)をはじめとする数多くのプロジェクトにも貢献している。
|
|
|
|