我需要修改默认的prestashop db查询。我尝试了以下内容:
public function ajaxProcessCheckProductName()
{
if ($this->tabAccess['view'] === '1')
{
$search = Tools::getValue('q'); /* in this variable, i wish subsitute the space with % */
$searchmod = str_replace(" ", "%", $search);
$id_lang = Tools::getValue('id_lang');
$limit = Tools::getValue('limit');
$result = Db::getInstance()->executeS('
SELECT DISTINCT pl.`name`, p.`id_product`, pl.`id_shop`
FROM `'._DB_PREFIX_.'product` p
LEFT JOIN `'._DB_PREFIX_.'product_lang` pl
ON (pl.`id_product` = p.`id_product` AND pl.`id_lang` = '.(int)$id_lang.')
WHERE pl.`name` LIKE "%'.pSQL($searchmod).'%"
GROUP BY pl.`id_product`
LIMIT '.(int)$limit);
die(Tools::jsonEncode($result));
}
}
我希望替换变量中的空格,例如kawasaki racing filter
和%,所以我可以使用完整的通配符对db进行查询...
示例:用户搜索kawasaki racing filter
,我希望将其替换为kawasaki%racing%filter
,因此查询将为%kawasaki%racing%filter%
...
这种方法似乎是正确的吗?它现在不起作用:(
有人能帮助我吗?提前谢谢!
答案 0 :(得分:1)
最不可能的原因是,如果您在数据库中搜索%kawasaki%racing%filter%
,它将按顺序搜索包含所有这些字词的条目。
我的预感是你期望它在字符串中的任何地方找到包含这三个单词的条目,但是你这样做的方式意味着它们必须按照它们输入的顺序出现。查询。
最好将字符串拆分为单独的单词,并独立搜索每个单词。
例如
... WHERE field LIKE '%kawasaki%'
AND field LIKE '%racing%'
AND field LIKE '%filter%'
这将搜索包含所有三个单词的记录,但是按任何顺序排列。如果您要查找其中任何一个单词,而不是全部三个单词,请将AND
替换为OR
。
此外:
如有必要,请不要忘记转义输入字符串。 (即,如果输入包含引号字符等,则防止SQL注入攻击,并防止查询中断)
如果可能,我建议您避免在查询中使用通配符。特别是在字符串的开头。这是因为它们可以使查询非常慢(DB必须读取每个记录,并为每个记录解析相关字段的全部内容:这是您可以在单个表上执行的最慢查询,如果您在同一时间做JOIN
,情况会更糟。)
在某些情况下,通配符搜索很有用,但是如果你需要进行大量的文本搜索,MySQL(和其他数据库;你没有指定你正在使用的数据库系统)确实有其他选项。
最简单的选择就是将关键字存储在单独的表中。您可以将它们视为标签。然后你可以直接查询确切的单词。
如果你需要更多,你可以查看MySQL的'Full Text Search' feature,这可以看作是减慢通配符搜索的直接替代品。
但即使这样有时也会很慢,所以如果你真的想要快,请查看Sphinx。这是一项更多的工作,但做得恰到好处,它会使你的搜索闪电般快速。
答案 1 :(得分:0)
确保您的Tools :: getValue不返回html字符串,例如。在你的情况下
。尝试var_dumpin你的工具:getValue,看看实际输出是什么。