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时,蛋糕不会为我们逃脱。因此,我们使用Sanitize实用程序手动进行转义,然后将%and_替换为\%and \_。不确定这是否 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

您将不得不使用Data Sanitization 类来实现相同的目的。希望它对你有用。

于 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 回答