0

検索条件でLIKE演算子を使用する場合:

<?php
array('OR' => array(
    array('Post.title LIKE' => '%one%'),
    array('Post.title LIKE' => '%two%')
))

...ワイルドカード文字をエスケープする組み込みのメカニズムがCakePHPにあるので、リテラルを検索したり、フォームなどの信頼できないソースから検索語を挿入したりできますか%_

<?php
array('OR' => array(
    array('Post.title LIKE' => '%' . $this->foo('100%') . '%'),
    array('Post.title LIKE' => '%' . $this->foo('red_apples') . '%')
                                            ^^^
))
4

3 に答える 3

2
App::uses('Sanitize', 'Utility'); // load Sanitize utility        
$db = $this->Model->getDataSource(); // get the datasource
$this->Model->find('all', array(
    'conditions' => array(
        'name LIKE' => $db->expression('\'%' . addcslashes(Sanitize::escape($userInput), '%_') . '%\'')
    )
));

私たちが使うとき$db->expression、ケーキは私たちのために逃げません。そのため、ユーティリティを使用して手動でエスケープを実行してから、andをandSanitizeに置き換えます。これが100%安全かどうかわからない場合は、安全ではないことがわかったらお知らせください。回答を更新できます。%_\%\_

あなたはそれを乾いた状態に保つためにあなたのためにこのすべてをするあなた自身のメソッドを作りたいでしょう

編集:に置き換えられましstr_replaceaddcslashes

Edit2:私はこれを複雑にしすぎていることに気づきました。ケーキを逃がさないようにしたい場合は、キーなしで値を指定することもできます。元。

'conditions' => array(
    'Post.title LIKE \'%' . addcslashes(Sanitize::escape($userInput), '%_') . '%\'',
)

どちらの方法でも

`Post`.`title` LIKE '%100\'\%\_%'

ユーザー入力用$userInput = "100'%_";

于 2012-08-14T07:19:59.573 に答える
0

同じことを実現するには、データサニタイズクラスを使用する必要があります。それがあなたのために働くことを願っています。

于 2012-08-14T07:17:44.083 に答える
0

最終的に、プリペアドステートメントを明示的に使用できることがわかりました。

<?php
$query = array('OR' => array(
    array(
        'Post.title LIKE ?' => array(
            '%' . $this->escapeLike('100%') . '%'),
        ),
    ),
    array(
        'Post.title LIKE ?' => array(
            '%' . $this->escapeLike('red_apples') . '%'),
        ),
    ),
);

...または、DBMSにデフォルトの区切り文字がない場合、またはデフォルトの区切り記号を設定する場合は、次のようにします。

<?php
$separator = '|';
$query = array('OR' => array(
    array(
        'Post.title LIKE ? ESCAPE ?' => array(
            '%' . $this->escapeLike('100%', $separator) . '%'),
            $separator
        ),
    ),
    array(
        'Post.title LIKE ? ESCAPE ?' => array(
            '%' . $this->escapeLike('red_apples', $separator) . '%'),
            $separator
        ),
    ),
);

私のescapeLike()方法は現在これです(それは決して難しい部分ではありませんでした):

/**
 * Escapes LIKE wildcard characters
 *
 * @param string $text
 * @param string $escape_character
 * @return string
 */
protected function escapeLike ($text, $escape_character='\\') {
    return strtr($text, array(
        '%'               => $escape_character . '%',
        '_'               => $escape_character . '_',
        $escape_character => $escape_character . $escape_character,
    ));
}

簡単にするために実装しましAppModelた(少なくとも私のプロジェクトでは)。

これは、MySQLアダプターを使用するCakePHP / 2.5で機能します(他のシナリオはわかりません)。

于 2017-01-13T12:23:02.060 に答える