自动完成基于SQL数据库的文本框结果

时间:2014-01-23 02:25:24

标签: php jquery html mysql autocompletebox

我正在尝试在文本框中创建自动完成功能,但结果应来自我的SQL数据库。

这是我正在尝试配置的代码:
的index.php

<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>jQuery UI Autocomplete - Default functionality</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
        <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
        <link rel="stylesheet" href="/resources/demos/style.css">
        <script>
            $(function() {
                var availableTags = [
                    "autocomplete.php"; ];
                $( "#tags" ).autocomplete({
                    source: availableTags
                });
            });
        </script>
    </head>
    <body>
        <div class="ui-widget">
            <label for="tags">Tags: </label>
            <input id="tags">
        </div>
    </body>
</html>

编辑:我更改了变量availableTags的内容并将其变为var availableTags = <?php include('autocomplete.php') ?>;

变量 availableTags 是单词的来源,所以我尝试更改它,而是放置一个文件名来从我的数据库中取出单词。

这是我的 autocomplete.php 文件:

 <?php

 include('conn.php');
 $sql="SELECT * FROM oldemp";
 $result = mysqli_query($mysqli,$sql) or die(mysqli_error());

 while($row=mysqli_fetch_array($result))
 {
 echo "'".$row['name']."', ";
 }
 ?>

编辑:还更改了while循环的内容并将其转换为

$name=mysqli_real_escape_string($con,$row['name']);
$json[]=$name;

如何将 autocomplete.php 中提取的单词插入 availableTags 变量?

编辑/更新:每当我在文本框中输入内容时,都会显示一个列表,但其中没有文字。我知道它正在提取,但这个词本身没有显示在列表中。

5 个答案:

答案 0 :(得分:4)

jQuery UI自动完成功能可以使用source option的3种不同类型的值:

  1. 数组,其中包含要使用
  2. 填写自动完成内容的列表
  3. 字符串,其中包含过滤列表并向我们发送结果的脚本的URL。该插件将输入文本并将其作为term参数发送到附加到我们提供的URL的查询字符串中。
  4. 函数,用于检索数据,然后使用该数据调用回调。
  5. 您的原始代码使用第一个数组。

    var availableTags = [
      "autocomplete.php";
    ];
    

    告诉自动填充的是,字符串"autocomplete.php"是自动填充的事物列表中唯一的东西。

    我认为你要做的就是把它嵌入这样的东西:

    $(function() {
    
      var availableTags = [
        <?php include("autocomplete.php"); /* include the output of autocomplete as array data */ ?>;
      ];
    
      $( "#tags" ).autocomplete({
        source: availableTags
      });
    
    });
    

    假设从数据库返回的事物列表总是很短,那么这可能会正常工作。这样做有点脆弱,因为你只是将PHP的原始输出推送到你的JS中。如果返回的数据包含",则可能必须使用addSlashes才能正确转义它。但是,您应该更改查询以返回单个字段而不是*,您可能只需要一个字段作为自动填充中的标签而不是整行。

    更好的方法,特别是如果列表可能会变得非常大,将使用第二种方法:

    $(function() {
    
      var availableTags = "autocomplete.php";
    
      $( "#tags" ).autocomplete({
        source: availableTags
      });
    
    });
    

    这将要求您对抓取列表的后端脚本进行更改,以便进行过滤。此示例使用prepared statement确保用户在$term中提供的数据无法向您开放SQL injection

    <?php
    
    include('conn.php');
    
    // when it calls autocomplete.php, jQuery will add a term parameter
    // for us to use in filtering the data we return. The % is appended
    // because we will be using the LIKE operator.
    $term = $_GET['term'] . '%';
    $output = array();
    
    // the ? will be replaced with the value that was passed via the
    // term parameter in the query string
    $sql="SELECT name FROM oldemp WHERE name LIKE ?";
    
    $stmt = mysqli_stmt_init($mysqli);
    
    if (mysqli_stmt_prepare($stmt, $sql)) {
    
      // bind the value of $term to ? in the query as a string
      mysqli_stmt_bind_param($stmt, 's', $term);
    
      mysqli_stmt_execute($stmt);
    
      // binds $somefield to the single field returned by the query
      mysqli_stmt_bind_result($stmt, $somefield);
    
      // loop through the results and build an array.
      while (mysqli_stmt_fetch($stmt)) {
          // because it is bound to the result
          // $somefield will change on every loop
          // and have the content of that field from
          // the current row.
          $output[] = $somefield;
      }
    
      mysqli_stmt_close($stmt);
    }
    
    mysqli_close($mysqli);
    
    // output our results as JSON as jQuery expects
    echo json_encode($output);
    
    ?>
    

    自从我使用mysqli以来已经有一段时间了,所以代码可能需要一些调整,因为它还没有经过测试。

    养成使用预准备语句的习惯会很好,因为正确使用后,它们就无法进行SQL注入。您可以使用普通的非预准备语句,在将每个用户提供的项目mysqli_real_escape_string转义到SQL语句之前转义它。 然而,这样做非常容易出错。它只需要忘记逃避一件事就可以让自己受到攻击。最近历史上的大多数major "hacks"都是由于编写SQL注入漏洞的草率编码所致。

    如果你真的想坚持使用非预备语句,那么代码应该是这样的:

    <?php
      include('conn.php');
    
      $term = $_GET['term'];
      $term = mysqli_real_escape_string($mysqli, $term);
      $output = array();
    
      $sql = "SELECT name FROM oldemp WHERE name LIKE '" . $term . "%';";
    
      $result = mysqli_query($mysqli,$sql) or die(mysqli_error());
    
      while($row=mysqli_fetch_array($result))
      {
        $output[] = $row['name'];
      }
    
      mysqli_close($mysqli);
    
      // output our results as JSON as jQuery expects
      echo json_encode($output);
    ?>
    

答案 1 :(得分:3)

当使用字符串时,Autocomplete插件希望该字符串指向将返回JSON数据的URL资源。

source: "autocomplete.php"

因此,您需要返回一个JSON对象。

$json = false;
while($row=mysqli_fetch_array($result))
{
    $json[] = array(
        'name' => $row['name']
    );
}
echo json_encode($json);

答案 2 :(得分:3)

您的autocomplete.php文件,

include('conn.php');
 $sql="SELECT * FROM oldemp";
 $result = mysqli_query($mysqli,$sql) or die(mysqli_error());

//Create an array
$arr = Array();
while($row=mysqli_fetch_array($result))
{
    array_push($arr,$row['name']);
}
header('Content-Type: application/json');
echo json_encode($arr)
?>

这样的结果将是一个可以直接在JavaScript中使用的JSON数组。 因此,脚本将类似于 -

var availableTags = [];
$.ajax({
    url:"autocomplete.php",success:function(result){
    availableTags = result
}});

答案 3 :(得分:3)

解决了我的问题。

让脚本像这样:

<!-- WITHOUT THESE THREE BELOW, THE AUTOCOMPLETE WILL LOOK UGLY OR WILL NOT WORK AT ALL -->
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>

<script>

  $(function() {
    $( "#tags" ).autocomplete({
      source: "autocomplete.php"
    });
  });

</script>

autocomplete.php 我们将获取数据以填充自动填充输入字段):

<?php

  include("conn.php"); /* ESTABLISH CONNECTION IN THIS FILE; MAKE SURE THAT IT IS mysqli_* */

  $stmt = $con->prepare("SELECT description FROM table"); /* START PREPARED STATEMENT */
  $stmt->execute(); /* EXECUTE THE QUERY */
  $stmt->bind_result($description); /* BIND THE RESULT TO THIS VARIABLE */
  while($stmt->fetch()){ /* FETCH ALL RESULTS */
    $description_arr[] = $description; /* STORE EACH RESULT TO THIS VARIABLE IN ARRAY */
  } /* END OF WHILE LOOP */

  echo json_encode($description_arr); /* ECHO ALL THE RESULTS */

?>

答案 4 :(得分:0)

仅提供自动填充文件的建议。对不起,我上面会添加一条评论,但是我写这篇文章时没有足够的代表。

成功实施无用代码的建议后,我注意到我的服务器开销正在通过屋顶。似乎机器人是如何启动脚本的,即使在输入区域没有输入字母。我对自动完成文件进行了一些测试,发现即使该术语为空,它也会查询我的数据库。

所以,我只是用if语句来填充整个自动完成脚本......就像这样......

<?php

if(!empty($_GET['term']))
{
include('conn.php');

$term = $_GET['term'];
$term = mysqli_real_escape_string($mysqli, $term);
$output = array();

$sql = "SELECT name FROM oldemp WHERE name LIKE '" . $term . "%';";

$result = mysqli_query($mysqli,$sql) or die(mysqli_error());

while($row=mysqli_fetch_array($result))
{
$output[] = $row['name'];
}

mysqli_close($mysqli);

// output our results as JSON as jQuery expects
echo json_encode($output);
}
?>

...现在我的服务器恢复正常了。