<?php
$searchErr="";
function test_input($data) {
$data = trim($data); //whitespacess
$data = stripslashes($data); //removes backslashes n clean data
from database or form
$data = htmlspecialchars($data); //converts predefinedto html
entities, encoding user input so that they cannot manipulate
html codes
return $data;
}
if ($_SERVER["REQUEST_METHOD"]=="POST")
{
if(isset($_POST["searchQuery"]))
{
if(empty($_POST["searchQuery"]))
{
$searchErr="Field cannot be empty!";
}
else //no error
{
$searchData=test_input($_POST["searchQuery"]);
$searchData=preg_replace("#[^0-9a-z]#i","",$searchData);
echo $searchData;
require_once('includes/db_connect.php');
$order=$category_filter="";
if (isset($_POST['price']) && !empty($_POST['price']))
{
$order="ORDER BY Food_Price(Rs) ";
if ($_POST['price']=='priceAsc')
{
if ($_POST['price']=='priceAsc')
{
$order.="ASC";
}
}
else
{
$order.="DESC";
}
}
if(isset($_POST['category']) && !empty($_POST['category']))
{
$foodType=$_POST['category'];
$category_filter="AND Food_Type='$foodType'";
}
$sQuery = "SELECT * FROM food "
. "WHERE ( LOWER(Food_Name) LIKE LOWER('%$searchData%') "
. "OR LOWER(Food_Description) LIKE LOWER('%$searchData%') ) "
. $category_filter
. $order;
echo "<pre>" . $sQuery . "</pre>";
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$results=$conn->query($sQuery);
$numResults=$results->rowCount();
if ($numResults==0)
{
$msg="No results found";
echo $msg;
}
else
{
while($row=$results->fetch(PDO::FETCH_ASSOC))
{
echo $row['Food_Name'];
echo "<br/>";
}
}
}
}
}
我是php的初学者,正在从事一个项目。我必须提示用户输入搜索查询并过滤结果,具体取决于价格(最低或最高)和食物类别。
我查了一下互联网,但不知道该怎么做。我必须限制选择语句的使用,并使代码更有效。没有过滤器的搜索工作完全正常。我该如何实现? 正在发布部分代码
编辑:唯一的问题是它放弃了我的Food_Price中的Rs,并告诉我Food_Price不存在。
答案 0 :(得分:-1)
您可以构建语句的一部分,然后将它们插入到查询字符串中,而不是按照注释中的要求使用多个sql。
我已经制作了两个示例,第一个示例只是获取有关如何构建查询的IDEA,它是独立的,因为它实际上并未与数据库进行交互。
第二个示例确实与数据库交互,并且我添加了准备好的语句以避免SQL注入。
示例1:没有准备好的台词的独立版本:
这个想法是,如果价格和/或类别为空,则会得到一个简单的查询,没有额外的过滤器,但是如果其中确实包含某些内容,则会创建required子句。
if(isset($_POST['submit'])) {
// define order
$order = '';
if(isset($_POST['price']) && !empty($_POST['price'])) {
$order = " ORDER BY Food_Price ";
if($_POST['price'] == 'priceAsc') {
$order .= "ASC";
} else {
$order .= "DESC";
}
}
// define category filter
$category_filter = '';
if (isset($_POST['category']) && !empty($_POST['category'])) {
$category_filter = " AND Food_Category = '" . $_POST['category']. "'";
}
// searchdata
$searchData = $_POST['searchData'];
// build query
$sQuery = "SELECT * FROM food "
. "WHERE ( LOWER(Food_Name) LIKE LOWER('%$searchData%') "
. "OR LOWER(Food_Description) LIKE LOWER('%$searchData%') ) "
. $category_filter
. $order;
// echo query
echo "<pre>" . $sQuery . "</pre>";
}
?>
<form method="POST">
<input type="text" name="searchData" value="Pepsi">
<input type="text" name="price" value="priceAsc">
<input type="text" name="category" value="Beverages">
<input type="submit" name="submit" value="Test">
</form>
输出:
没有价格或类别,您会得到:
SELECT * FROM food WHERE ( LOWER(Food_Name) LIKE LOWER('%Pepsi%') OR LOWER(Food_Description) LIKE LOWER('%Pepsi%') )
通过价格和类别,您将获得:
SELECT * FROM food WHERE ( LOWER(Food_Name) LIKE LOWER('%Pepsi%') OR LOWER(Food_Description) LIKE LOWER('%Pepsi%') ) AND Food_Category = 'Beverages' ORDER BY Food_Price ASC
示例2:使用准备好的语句,需要数据库进行测试:
此示例要求存在一个db,但由于连接是在同一文件中进行的,因此它仍然是独立的(为简单起见)。只需检查列名称是否与您的名称匹配,因为我不确定您所用的实际名称是什么。
if(isset($_POST['submit'])) {
// Create connection (put on a separated file, this is just an example)
$username = "root";
$password = "";
$dsn = "mysql:host=localhost;dbname=food;charset=utf8mb4";
$options = [
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
$pdo = new PDO($dsn, $username, $password, $options);
} catch (Exception $e) {
error_log($e->getMessage());
exit('Something went wrong.');
}
// define order
$order = '';
if(isset($_POST['price']) && !empty($_POST['price'])) {
$order = " ORDER BY Food_Price ";
if($_POST['price'] == 'priceAsc') {
$order .= "ASC";
} else {
$order .= "DESC";
}
}
// define category filter
$category_filter = '';
if (isset($_POST['category']) && !empty($_POST['category'])) {
$category_filter = " AND Food_Category = :category";
}
// build query
$sQuery = "SELECT * FROM food "
. "WHERE ( LOWER(Food_Name) LIKE LOWER(:searchData1) "
. "OR LOWER(Food_Description) LIKE LOWER(:searchData2) )"
. $category_filter
. $order;
// echo query
echo "<pre>" . $sQuery . "</pre>";
// prepare statement
$stmt = $pdo->prepare($sQuery);
// bind values
if(!empty($category_filter)) {
$stmt->bindParam(':category', $_POST['category'], PDO::PARAM_INT);
}
$searchData = '%' . $_POST['searchData'] . '%';
// I have to do it twice due to this: https://bugs.php.net/bug.php?id=40417
$stmt->bindParam(':searchData1', $searchData, PDO::PARAM_STR);
$stmt->bindParam(':searchData2', $searchData, PDO::PARAM_STR);
// execute statement
$stmt->execute();
// fetch
$arr = $stmt->fetchAll();
if(!$arr) {
echo 'No rows matching the criteria.';
} else {
echo "<pre>";
print_r($arr);
echo "</pre>";
}
}
?>
<form method="POST">
<input type="text" name="searchData" value="Pepsi">
<select name="price">
<option value="priceAsc">Ascending Price</option>
<option value="priceDesc">Descending Price</option>
</select>
<input type="text" name="category" value="Beverages">
<input type="submit" name="submit" value="Test">
</form>