Autofuldførelsen af jQuery UI kan tage 3 forskellige typer værdier af kildeindstillingen :
- En matrix indeholdende listen over ting, der skal udfyldes automatisk komplet med
- En streng indeholdende URL'en til et script, der filtrerer en liste og sender os resultaterne. Pluginnet vil tage tekst indtastet i det og sende det som en
term
parameter i en forespørgselsstreng tilføjet til den URL, vi har angivet. - En funktion der henter dataene og derefter kalder et tilbagekald med disse data.
Din originale kode bruger den første, et array.
var availableTags = [
"autocomplete.php";
];
Det, der fortæller autofuldførelsen, er, at strengen "autocomplete.php"
er det eneste på listen over ting, der skal autofuldføres med.
Jeg tror, det du prøvede at gøre, er at indlejre det med noget som dette:
$(function() {
var availableTags = [
<?php include("autocomplete.php"); /* include the output of autocomplete as array data */ ?>;
];
$( "#tags" ).autocomplete({
source: availableTags
});
});
Det ville sandsynligvis fungere okay, hvis vi antager, at listen over ting, der returneres fra databasen, altid vil forblive kort. At gøre det på denne måde er dog lidt skrøbeligt, da du bare skubber rå output fra PHP ind i din JS. Hvis de returnerede data indeholder "
du skal muligvis bruge addSlashes
at undslippe det korrekt. Du bør dog ændre forespørgslen til at returnere et enkelt felt i stedet for *
, vil du sandsynligvis kun have ét felt som etiketten i autofuldførelsen, ikke hele rækken.
En bedre tilgang, især hvis listen potentielt kunne blive meget stor, ville være at bruge den anden metode:
$(function() {
var availableTags = "autocomplete.php";
$( "#tags" ).autocomplete({
source: availableTags
});
});
Dette kræver, at du foretager en ændring af back-end-scriptet, der griber listen, så det udfører filtreringen. Dette eksempel bruger en forberedt erklæring
for at sikre, at brugeren har leveret data i $term
åbner dig ikke for SQL-injektion
:
<?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);
?>
Det er et stykke tid siden, jeg har arbejdet med mysqli, så den kode skal muligvis justeres, da den ikke er blevet testet.
Det ville være godt at vænne sig til at bruge forberedte sætninger, da de, når de bruges korrekt, gør SQL-injektion umulig. Du kan i stedet bruge en normal ikke-forberedt erklæring, hvor du undslipper hvert brugerleveret element med mysqli_real_escape_string før du indsætter det i din SQL-sætning. Men , at gøre dette er meget udsat for fejl. Det kræver kun at glemme at undslippe én ting for at åbne dig op for angreb. Det meste af større "hacks" i nyere historie skyldes sjusket kodning, der introducerer SQL-injektionssårbarheder.
Hvis du virkelig vil holde fast i den ikke-forberedte sætning, vil koden se nogenlunde sådan ud:
<?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);
?>