プロジェクトのチーム リーダーを務めていたとき (バージョン 1.0 まで)、Zend Framework でデータベース パラメーターと引用符のコードを大量に作成しました。
可能な限りベスト プラクティスを奨励しようとしましたが、使いやすさとのバランスを取る必要がありました。
Zend_Db_Select
オブジェクトの文字列値をいつでも調べて、引用 符を付ける方法を確認できることに注意してください。
print $select; // invokes __toString() method
Zend_Db_Profiler
を使用して、 が代わりに実行する SQL を検査することもできますZend_Db
。
$db->getProfiler()->setEnabled(true);
$db->update( ... );
print $db->getProfiler()->getLastQueryProfile()->getQuery();
print_r $db->getProfiler()->getLastQueryProfile()->getQueryParams();
$db->getProfiler()->setEnabled(false);
特定の質問に対するいくつかの回答を次に示します。
Zend_Db_Select::where('last_name=?', $lname)
値は適切に引用されています。" ?
" はパラメーターのプレースホルダーのように見えますが、このメソッドでは、実際には引数が適切に引用され、補間されます。したがって、これは真のクエリ パラメータではありません。実際、次の 2 つのステートメントは、上記の使用法とまったく同じクエリを生成します。
$select->where( $db->quoteInto('last_name=?', $lname) );
$select->where( 'last_name=' . $db->quote($lname) );
ただし、 type のオブジェクトであるパラメーターを渡す場合Zend_Db_Expr
、それは引用符で囲まれません。SQL インジェクションのリスクは、式の値をサポートするために逐語的に補間されるため、責任があります。
$select->where('last_modified < ?', new Zend_Db_Expr('NOW()'))
引用または区切りが必要な式のその他の部分は、ユーザーの責任です。たとえば、PHP 変数を式に挿入する場合、安全性はユーザーの責任です。SQL キーワードである列名がある場合は、それらを で区切る必要がありますquoteIdentifier()
。例:
$select->where($db->quoteIdentifier('order').'=?', $myVariable)
Zend_Db_Adapter_Abstract::insert( array('colname' => 'value') )
をオフにしない限り、テーブル名と列名は区切られますAUTO_QUOTE_IDENTIFIERS
。
値は真のクエリ パラメータとしてパラメータ化されます (補間されません)。Zend_Db_Expr
値がオブジェクトでない限り、その場合は逐語的に補間されるため、式などを挿入できますNULL
。
Zend_Db_Adapter_Abstract::update( array('colname' => 'value'), $where )
をオフにしない限り、テーブル名と列名は区切られますAUTO_QUOTE_IDENTIFIERS
。
Zend_Db_Expr
メソッドのように、値がオブジェクトでない限り、値はパラメーター化されinsert()
ます。
引数はまったくフィルター処理されないため、その$where
引数での SQL インジェクションのリスクについてはユーザーが責任を負います。この方法を利用すると、quoteInto()
引用がより便利になります。