ここでは、Zend Framework-1.11 による PHP から各種データベースへのクエリ発行時に行う SQL 文のクォート処理の実装例を掲載しています。エスケープによる SQL インジェクション対策は必須ともいえます。
スポンサーリンク
Oracle
protected function _quote($value)
{
if (is_int($value) || is_float($value)) {
return $value;
}
$value = str_replace("'", "''", $value);
return "'" . addcslashes($value, "\000\n\r\\\032") . "'";
}
MySQL ( mysqli ) ※ 一部修正
protected function _quote($value)
{
if (is_int($value) || is_float($value)) {
return $value;
}
$connect = mysqli_init();
return "'" . $connect->real_escape_string($value) . "'";
}
SQL Server
protected function _quote($value)
{
if (is_int($value)) {
return $value;
} elseif (is_float($value)) {
return sprintf('%F', $value);
}
return "'" . str_replace("'", "''", $value) . "'";
}
DB2 ※ 一部修正
protected function _quote($value)
{
if (is_int($value) || is_float($value)) {
return $value;
}
/**
* Use db2_escape_string() if it is present in the IBM DB2 extension.
* But some supported versions of PHP do not include this function,
* so fall back to default quoting in the parent class.
*/
if (function_exists('db2_escape_string')) {
return "'" . db2_escape_string($value) . "'";
}
// db2_escape_string 関数未サポート環境の場合
if (is_int($value)) {
return $value;
} elseif (is_float($value)) {
return sprintf('%F', $value);
}
return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'";
}
PDO
PDO ドライバの多くは quote メソッドを実装しているので そのまま使用することができますが、ZendFramework-1.11 によれば oracle の場合は実装する必要があるとのことです。
// Zend/Db/Adapter/Pdo/Oci.php 内のコメントから抜粋 /** * Quote a raw string. * Most PDO drivers have an implementation for the quote() method, * but the Oracle OCI driver must use the same implementation as the * Zend_Db_Adapter_Abstract class. * * @param string $value Raw string * @return string Quoted string */
Zend_Db で SQL をクォート ( Zend Framework-1.11 )
次に、実際に ZendFramework の Zend_Db アダプタを使用して SQL のクオート処理を行います。なお、処理結果は Zend_Db_Adapter_Oracle アダプタを使用した場合のものです。
// DB アダプタを取得
$adpt = Zend_Db::factory($config->database);
// データベースへ接続
$adpt->getConnection();
// クォート処理(quote メソッド)
$str = "I'am boy";
$quote = $adpt->quote($str);
// クォート処理実施後の文字列
// 'I''am boy'
// クォート処理(quoteInto メソッド)
$into = "col1 = ?";
$quoteinto = $adpt->quoteInto($into, $str);
// クォート処理実施後の文字列
// col1 = 'I''am boy'
/*
* この位置でSQL を組み立てて SQL の発行など行う。
*/
// データベースから切断
$adpt->closeConnection();
サンプルの動作結果では正常に文字列がクォート処理が実施されていることが確認できます。 ただし、SQL 用に最適化されているため、文字列の前後にシングルコーテーションが自動で付与されています。なお、数値の場合はシングルコーテーションは付与されません。
文字列の前後のシングルクォーテーションを付与させない
Zend_Db_Expr クラスを使用することで文字列の前後のシングルコーテーションの自動付与をさせなくできます。例えば Oracle へのレコード挿入時に SYSDATE などで現在日時を設定している場合などのケースが考えられます。ただし、Zend_Db_Expr クラスを使用した場合はクォート処理も行われないので注意が必要です。
// select 文の発行 $str = "SYSDATE"; $quote = $adpt->quote(new Zend_Db_Expr($str)); // クォート処理実施後の文字列 // SYSDATE $into = "mdate = ?"; $quoteinto = $adpt->quoteInto($into, new Zend_Db_Expr($str)); // クォート処理実施後の文字列 // mdate = SYSDATE
Pingback: PHP5.4.0 でマジッククォートは削除されました ( magic_quotes_* ) – 勉強ダイエット