[ PHP ] SQL のクォート ( Oracle, MySQL, SQL Server, DB2 )

Pocket

ここでは、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
スポンサーリンク


Pocket

One thought on “[ PHP ] SQL のクォート ( Oracle, MySQL, SQL Server, DB2 )”

  1. Pingback: PHP5.4.0 でマジッククォートは削除されました ( magic_quotes_* ) – 勉強ダイエット

Leave a Comment

Your email address will not be published. Required fields are marked *