我正在尝试使用PHP和PDO编写简单的全文搜索。我不太确定通过SQL和PDO搜索数据库的最佳方法是什么。我找到了这个this脚本,但它是旧的MySQL扩展。我写了这个函数,女巫应该计算搜索匹配,但SQL不起作用。传入的搜索字符串如下所示:23+more+people
function checkSearchResult ($searchterm) {
//globals
global $lang; global $dbh_pdo; global $db_prefix;
$searchterm = trim($searchterm);
$searchterm = explode('+', $searchterm);
foreach ($searchterm as $value) {
$sql = "SELECT COUNT(*), MATCH (article_title_".$lang.", article_text_".$lang.") AGINST (':queryString') AS score FROM ".$db_prefix."_base WHERE MATCH (article_title_".$lang.", article_text_".$lang.") AGAINST ('+:queryString')";
$sth = $dbh_pdo->prepare($sql);
$sql_data = array('queryString' => $value);
$sth->execute($sql_data);
echo $sth->queryString;
$row = $sth->fetchColumn();
if ($row < 1) {
$sql = "SELECT * FROM article_title_".$lang." LIKE :queryString OR aricle_text_".$lang." LIKE :queryString";
$sth = $dbh_pdo->prepare($sql);
$sql_data = array('queryString' => $value);
$sth->execute($sql_data);
$row = $sth->fetchColumn();
}
}
//$row stays empty - no idea what is wrong
if ($row > 1) {
return true;
}
else {
return false;
}
}
答案 0 :(得分:2)
准备$sql_data
数组时,需要在参数名前加冒号:
array('queryString' => $value);
应该是:
array(':queryString' => $value);
在您的第一个SELECT
中,您有AGINST
而不是AGAINST
。
您的第二个SELECT
似乎缺少FROM
后的表名和WHERE
子句。 LIKE
参数的格式也不正确。它应该是这样的:
sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE '%:queryString%' OR aricle_text_".$lang." LIKE '%:queryString%'";
更新1&gt;&gt;
对于两个 SELECT
语句,您需要为每个参数指定唯一标识符,并且LIKE
通配符应放在值中,而不是语句中。所以你的第二个陈述应该是这样的:
sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE :queryString OR aricle_text_".$lang." LIKE :queryString2";
注意queryString1
和queryString2
,不带引号或%
通配符。然后,您还需要更新阵列:
$sql_data = array(':queryString1' => "%$value%", ':queryString2' => "%$value%");
有关使用具有相同值的多个参数的详细信息,请参阅PDOStatement->execute的参数部分。因此,我倾向于使用问号作为占位符,而不是命名参数。我发现它更简单,更整洁,但这是一个选择问题。例如:
sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE ? OR aricle_text_".$lang." LIKE ?";
$sql_data = array("%$value%", "%$value%");
<强>&LT;&LT;更新结束1
我不确定第二个SELECT
的含义是什么,因为我认为如果第一个SELECT
找不到查询值,第二个也找不到它。但我对MySQL全文搜索没有做太多,所以我可能会遗漏一些东西。
无论如何,你真的需要仔细检查SQL和任何错误。您可以通过打印PDOStatement->errorCode
:
$sth->execute($sql_data);
$arr = $sth->errorInfo();
print_r($arr);
更新2&gt;&gt;
值得一提的另一点是:确保在将变量插入SQL语句时,只使用可信数据。也就是说,不允许用户提供的数据用于表名或列名。您使用预准备语句非常棒,但这些只保护参数,而不是SQL关键字,表名和列名。所以:
"SELECT * FROM ".$db_prefix."_base"
...正在使用变量作为表名的一部分。确保此变量包含可信数据。如果它来自用户输入,请先将其与白名单进行核对。
<强>&LT;&LT;更新结束1
您应该阅读MySQL Full-Text Search Functions和String Comparison Functions。您需要学习如何构造基本的SQL语句,否则编写一个简单的搜索引擎将非常困难。
PHP网站上也有很多PDO示例。您可以从PDOStatement->execute的文档开始,其中包含有关如何使用该函数的一些示例。
如果您可以访问MySQL CLI,甚至是PHPMyAdmin,那么您可以在没有PHP混乱的情况下试用SQL。如果您要作为PHP应用程序的一部分进行任何数据库开发工作,您将发现能够独立于PHP测试SQL是一个很好的帮助。