Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 我想在搜索栏中搜索一个或多个单词_Php_Sql_Pdo - Fatal编程技术网

Php 我想在搜索栏中搜索一个或多个单词

Php 我想在搜索栏中搜索一个或多个单词,php,sql,pdo,Php,Sql,Pdo,当我输入一个单词时,我的查询总是有效的,但是当我输入多个单词时,查询会很奇怪。它会丢失相同类别中的一些视频,并获取不在相同类别中的一些视频。我打赌它必须与查询中的“AND”&“或”有关,但我不确定 这是我的密码 if(isset($_GET['search']) AND !empty($_GET['search']) AND $_GET['search'] != ' ') { $search = htmlspecialchars($_GET['search']); $search

当我输入一个单词时,我的查询总是有效的,但是当我输入多个单词时,查询会很奇怪。它会丢失相同类别中的一些视频,并获取不在相同类别中的一些视频。我打赌它必须与查询中的“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;
    }
}
if(设置($\u-GET['search'])和!空($\u-GET['search'])和$\u-GET['search'])!=“”){
$search=htmlspecialchars($_GET['search']);
$searchArray=explode(“”,$search);
$videos=$stdb->prepare('从类别如“skateboard”和标题如“%”的视频中选择id、标题、videoTime。内爆(“\”或标题如“%”,$searchArray)。“%”按id顺序描述限制“$start.”,“$videosPerPage”);
$videos->execute();
$totalVideosReq=$stdb->prepare('从视频中选择id,其中类别如“滑雪板”和标题如“%”。内爆(“\”或标题如“%”,$searchArray)。“%”按id顺序描述);
$totalVideosReq->execute();
$totalVideos=$totalVideosReq->rowcount();
var_dump($totalVideos);
$totalPages=ceil($totalVideos/$videosPerPage);
$currentPage=1;

如果(isset($\u GET['page'])和!empty($\u GET['page'])和$\u GET['page']>0和$\u GET['page']我相信你缺少了一个结束百分比来概括类似的东西。我想你是在追求:

$stdb->prepare('SELECT id FROM videos WHERE categories LIKE "snowboard" AND title LIKE "%'.implode("%\" OR title LIKE \"%", $searchArray).'%" ORDER BY id DESC');

偏好的问题是由于
功能的方式导致的

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'
为了将该类别应用于搜索的所有标题,您需要将
括在括号
()
中,类似于PHP if条件


在注释中回答您的问题;使用
bindParam
execute($parameters)
将提供更安全的查询。您不能为占位符值传递值数组

例如:
bindParam(':searchArray',['Hello','World'])
不起作用

对于所需的每个
如“%search\u 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);
结果:

见:

  • 为了 有关使用参数和占位符的详细信息
  • 有关已编制报表的一般信息

另外,对于您的第二个查询,我将改为read

$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);
orderby
将减慢查询速度,您不需要从数据库返回行来计数,因为MySQL可以为您这样做


有关
rowCount
及其与
SELECT
语句的用法的参考信息,请参阅。

否,
$search
的分解不会阻止SQL注入,但由于在空格上的分解会更加困难。更好的方法是利用
rtrim(str_repeat('title LIKE?OR',count($searchArray)),'OR'))
然后在占位符上添加
bindValues
,或者添加到
$parameters
数组中,以传递到准备好的语句的
execute()
如果我这样做:
$videos->bindParam(':searchArray',$searchArray);
并在查询中将$searchArray替换为:searchArray就可以了吗?它对“%”做同样的事情但是如果我在搜索栏中输入一个以上的单词,它会在查询中添加更多的“或标题”以及“WHERE categories LIKE”,比如“skateboard”“lose是优先级,但我不知道为什么!你能发布完整的查询吗?这可能会有帮助。非常感谢你的回答!这是一个很大的帮助,而且非常详细。唯一的问题是我不太明白
$parameters
$likes
如何保护我的查询不受SQL注入的影响。对于第二个查询,在删除无用的查询之后
orderbydesc
,是否最好使用:
selectcount(id)
whit
$totalVideos=$stdb->fetchColumn();
selectid
whit
$totalVideos=$totalVideosReq->rowcount();
?这有什么区别吗?SQL注入是由人们操纵表单字段来运行恶意查询,因为他们直接在SQL语句中接受接收到的值。
$parameters
告诉SQL Server,它们不会作为
SQL
运行,而是作为占位符。开发人员会使用一些方法,例如特殊字符转义,以及其他一些方法,可以绕过
爆炸
添加斜杠
htmlentities
mysqli_real_escape_string
等问题。如果答案有用,请对其进行更新投票,或者在解析时将其标记为接受d您的问题,以便其他人知道您的问题已得到回答。使用
行数
,您将向服务器发出第二个查询,以便服务器报告上次执行的查询中受影响的行,并且与
选择
一起使用时,结果并不总是准确。最好将其保留用于
更新
插入RT
DELETE
语句检索受影响记录的数量。如果发出单个
计数
查询,则会更快并准确地获得相同的结果。
$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);