在数据库中搜索与DATAS准备语句

问题描述 投票:1回答:1

一个快速的问题:),我写了这个,因为有人说我的代码很容易受到MySQL的注入,它是学习准备的语句在网络编程,以避免任何用户将恶意数据或语句转换成database..What我有一个要求从数据库中检索数据,如果你在这样“托雷斯”然后我搜索托雷斯,但如果你只是把“TOR”它不会搜索包含“TOR”在他们的名字DATAS字符串类型的搜索功能。 。我不知道正确的格式,而使用事先准备好的声明,如果你有意见,我感到非常高兴把它:)

    <?php
if (isset($_POST['search'])) {

    $box = $_POST['box'];
    $box = preg_replace("#[^0-9a-z]#i","",$box);
    $grade =$_POST['grade'];
    $section = $_POST['section'];
    $strand = $_POST['strand'];




      $sql = "SELECT * FROM student WHERE fname LIKE ? or lname LIKE ? or mname LIKE ? or grade = ? or track = ? or section = ?";
        $stmt = mysqli_stmt_init($conn);
        if (!mysqli_stmt_prepare($stmt, $sql)){
            echo "SQL FAILED";
        }
        else {
            //bind the parameter place holder
            mysqli_stmt_bind_param($stmt, "ssssss",$box, $box, $box, $grade, $strand, $section);
            mysqli_stmt_execute($stmt);
            $result = mysqli_stmt_get_result($stmt);

            while($row = mysqli_fetch_assoc($result))
        {
            echo "<tr>";
            echo "<td>".$row['lname']."</td>";
            echo "<td>".$row['fname']."</td>";
            echo "<td>".$row['mname']."</td>";
            echo "<td>".$row['grade']."</td>";
            echo "<td>".$row['track']."</td>";
            echo "<td>".$row['section']."</td>";
       echo "</tr>";
        }

        }
php html
1个回答
1
投票

按照要求:

@ArtisticPhoenix我明明喜欢国王的方式[复合全文索引。这应该是表示实施例/交代你的主要答案。

首先要包含所有三个字段(这是在phpMyAdmin,这是一个有点容易用图像来解释)全文索引

enter image description here

然后做这样的查询:

#PDO version SELECT * FROM `temp` WHERE MATCH(fname,mname,lname)AGAINST(:fullname IN BOOLEAN MODE)
#MySqli version SELECT * FROM `temp` WHERE MATCH(fname,mname,lname)AGAINST(? IN BOOLEAN MODE)
SELECT * FROM `temp` WHERE MATCH(fname,mname,lname)AGAINST('edward' IN BOOLEAN MODE)

enter image description here

这看似简单,但也有一些事情全文要知道闵字符数是3的(我认为)什么比这更小的不搜索上。这是可以改变的,但它需要修复DB并重新启动MySQL的。

停止的话,这些东西等andthe等,这些也可以在my.cnf配置。

标点符号被忽略。这可能不会在名称的大交易,但认为复姓姓氏。

一般我分钟减少到字2和指向所述停用词到一个空文件(禁止它们)。

对语法的比赛是完全不同的,它是非常强大的,但它不是真正使用全文之外。一个例子是:这是外卡*你使用精确短语匹配'"' '"match exactly"'双引号,和+是逻辑与,如word+ word+(默认为OR),-是,如果我还记得不匹配,这等......没错,我在几年前用它了一堆,但还没有到最近使用它。

例如做一个局部字“开头”

SELECT * FROM `temp` WHERE MATCH(fname,mname,lname)AGAINST('edwar*' IN BOOLEAN MODE)

同样的结果相匹配一行。最明显的好处是在同一时间搜索所有3场,但全文语法本身可以说是相当有用的。

欲获得更多信息:

https://dev.mysql.com/doc/refman/8.0/en/fulltext-boolean.html

PS。我想补充一点在查询中使用OR真的可以杀死的表现,我去就因的表现有多么糟糕的一大桌与OR更换简单UNION。在逻辑上,DB优化器必须重新扫描整个表的OR,不像AND它可以使用以前的表达式的结果,以减少下一个表达式的数据集(或者说是我的理解它)。我可以说,使用或VS UNION的性能差异非常显着。

这是一个复合全文索引VS做或单独对每个字段如此。默认情况下,全文是快,但它甚至更快的这种方式。

To fix your current query (for the sake of completeness)

你需要什么作为独家或,这样知:

SELECT * FROM student WHERE ( fname LIKE ? OR lname LIKE ? OR mname LIKE ? ) AND grade = ? AND track = ? AND section = ?

这样做是组或一起来,让他们evalute作为一个表达的“下一级”(括号外)。基本上的操作顺序。在英语中,你必须匹配这些列fnamelnamemname至少1,您也必须匹配所有列的其余部分为好,得到返回的任何给定行的结果。

  • 如果你使用的所有OR(你现在的样子)和任何单场相匹配,那么查询带有火柴回来为真。这是你现在所遇到的行为。
  • 如果您只需更改姓名字段以外的一切AND,基本上去掉括号

像这样:

 #this is wrong don't use it.
 SELECT * FROM student WHERE fname LIKE ? OR lname LIKE ? OR mname LIKE ? AND grade = ? AND track = ? AND section = ?

然后,你必须这样匹配。

 (grade AND track AND section AND mname) OR lname OR fname 

因此,如果最后一个或第一个名字的比赛,你得到的结果,无论任何其他领域的。但是,你会发现mname场必须匹配字段的其余所有的人得到的结果(但你可能不会另行通知)。因为,它似乎是在查询的工作你如何想,但只有当mname匹配。

我希望这是有道理的。这可能是认为WHERE子句是相同的逻辑规则的IF条件的帮助。

干杯!

© www.soinside.com 2019 - 2024. All rights reserved.