当我输入1个单词时,我的查询总是有效,但当我输入多个单词时,查询很奇怪。它错过了相同类别的某些视频,并获得了不属于同一类别的视频。我打赌它必须做“AND”和&查询中的“或”,但我不确定。
这是我的代码。
if(isset($_GET['search']) AND !empty($_GET['search']) AND $_GET['search'] != ' ') {
$search = htmlspecialchars($_GET['search']);
$searchArray = explode(' ',$search);
$videos = $stdb->prepare('SELECT id, title, videoTime FROM videos WHERE categories LIKE "skateboard" AND title LIKE "%'.implode("\" OR title LIKE \"%", $searchArray).'%" ORDER BY id DESC limit '.$start.','.$videosPerPage);
$videos->execute();
$totalVideosReq = $stdb->prepare('SELECT id FROM videos WHERE categories LIKE "snowboard" AND title LIKE "%'.implode("\" OR title LIKE \"%", $searchArray).'%" ORDER BY id DESC');
$totalVideosReq->execute();
$totalVideos = $totalVideosReq->rowcount();
var_dump($totalVideos);
$totalPages = ceil($totalVideos/$videosPerPage);
$currentPage = 1;
if(isset($_GET['page']) AND !empty($_GET['page']) AND $_GET['page'] > 0 AND $_GET['page'] <= $totalPages) {
$_GET['page'] = intval($_GET['page']);
$currentPage = $_GET['page'];
} else {
$currentPage = 1;
}
}
有人知道,由于$searchArray
是explode()
的{{1}},查询是否可以安全地从SQL注入?
答案 0 :(得分:0)
我相信你错过了一个结束%来绕过LIKE。我想你是在追求:
$stdb->prepare('SELECT id FROM videos WHERE categories LIKE "snowboard" AND title LIKE "%'.implode("%\" OR title LIKE \"%", $searchArray).'%" ORDER BY id DESC');
答案 1 :(得分:0)
偏好问题是由OR
函数的方式导致的。
if ($category == 'snowboard' AND $title == 'first_string') {
record
} elseif ($title == 'second_string') {
record
} ... etc
允许您执行以下单独的条件:
category = 'snowbord' AND title = 'first_string'
OR
category = 'ski' AND title = 'second_string'
为了将类别应用于所搜索的所有标题,您需要将OR
括在括号()
中,类似于PHP中的条件。
在评论中回答你的问题;使用bindParam
或execute($parameters)
可以提供更安全的查询。您不能传递占位符值的值数组。
例如:bindParam(':searchArray', ['Hello', 'World'])
无效。
您需要为每个LIKE '%search_string%'
提供单独的占位符和参数。
$search = "Hello World";
$searchArray = explode(' ', $search);
//create a like condition for each search word
$likes = rtrim(str_repeat('title LIKE ? OR ', count($searchArray)), ' OR ');
//surround each search word with '%' to find strings containing the word
$parameters = array_map(function($value) { return '%' . $value . '%'; }, $searchArray);
$query = 'SELECT id, title, videoTime
FROM videos
WHERE categories LIKE "skateboard"
AND (' . $likes . ')
ORDER BY id DESC
LIMIT '. $start . ',' . $videosPerPage;
$videos = $stdb->prepare($query);
$videos->execute($parameters);
var_dump($query);
var_dump($parameters);
#query
string(141) "SELECT id, title, videoTime
FROM videos
WHERE categories LIKE "skateboard"
AND (title LIKE ? OR title LIKE ?)
ORDER BY id DESC
LIMIT 1,20"
#parameters
array(2) {
[0]=>
string(7) "%Hello%"
[1]=>
string(7) "%World%"
}
请参阅:
此外,对于您的第二个查询,我将更改为阅读。
$query = 'SELECT COUNT(id)
FROM videos
WHERE categories LIKE "snowboard"
AND ('. $likes .')';
$totalVideosReq = $stdb->prepare($query);
$totalVideosReq->execute($parameters);
$totalVideos = $stdb->fetchColumn();
var_dump($totalVideos);
$totalPages = ceil($totalVideos/$videosPerPage);
ORDER BY
将减慢查询速度,并且您无需返回数据库中的行进行计数,因为MySQL可以为您执行此操作。
有关rowCount
的参考信息,请参阅http://php.net/manual/en/pdostatement.rowcount.php#example-1049,并将其用于SELECT
语句。