1

我目前有一个 php 页面,它从数据库中获取信息并生成带有数据属性的 HTML,这些数据属性由 MySQL 查询填充。该数据库将用于搜索,有许多不同的搜索选项。

我需要帮助的是知道一种方法来组织如何处理许多变量。这是一个非常混乱的代码,即使我放了所有的评论,它也让我头疼,试图弄清楚如何在搜索中添加另一个变量。

除了 LIMIT 到哪一行和多少个结果之外,所有变量都是可选的。因此,如果有人将除此空白之外的所有内容都留下,我仍然希望它能够像他们精心填写所有字段一样发挥作用。

这就是我所拥有的,有 6 个变量。

<?php
$product_size = "(".$_GET['size']." BETWEEN productsizeDOWN AND productsizeUP)";  // This code sets the variable to input into the MySQL string based on the URL
$product_size_check = $_GET['size'];    // the _checks check are used to see if the value is or isn't empty using if statements below
$manufacturer = $_GET['manufacturer']; 
$product_manufacterer_check = $_GET['manufacturer']; // _check
$product_invisible = "(hideproduct = '".$_GET['invisible']."')"; // Checks if product is hidden
$product_invisible_check = $_GET['invisible']; // _check
$product_instock_check = $_GET['instock']; // _check
$product_limit0 = $_GET['startat']; // This is the first number after LIMIT; the row to start in.
$product_limit1 = $_GET['results']; // This is how many results to load.

    $manufacturer_array = explode(",", $manufacturer); // The manufacturer comes in as "Nike,Addidas,Rebok" and is turned into an array
    $manufacturer_imploded = implode("' OR productmanufacturer = '", $manufacturer_array); // Puts it back together with "OR productmanufacturer =" between each name.
    $product_manufacterer = ("(productmanufacturer = '".$manufacturer_imploded."')"); // formats it so it can be directly inserted into MySQL string with a WHERE in front.

if($product_invisible_check == ""){
    $product_invisible = "";
}else{$where = "WHERE ";};  //Useless code that I havn't deleted that I tried to use when I searched the entire database
if($product_size_check == ""){
    $product_size = "";
}else{$where = "WHERE ";};
if($product_manufacterer_check == ""){
    $product_manufacterer = "";
}else{$where = "WHERE ";};
if($product_instock_check == "N"){ 
    $product_instock = "(stockstatus <= '0' AND donotallowbackorders = 'Y') AND "; // Checks if product is in stock (Allowing backordering OR stock >1)
    $where = "WHERE ";
}
elseif($product_instock_check == "Y") {
    $product_instock = "(stockstatus > '0' OR donotallowbackorders = 'N') AND ";
    $where = "WHERE ";
}
else {
    $product_instock = "";
};

$sql="Select * FROM ioa7pd_Products WHERE ".$product_instock.$product_size."AND".$product_manufacterer_and.$product_manufacterer."".$product_invisible." LIMIT ".$product_limit0.", ".$product_limit1; // The end result of it all. 
echo $sql;
    ?>

当 URL 是

test.php?size=5&manufacturer=Nike,Addidas,Rebok&invisible=N&instock=Y&startat=0&results=30

生成的 SQL 查询是

Select * FROM ioa7pd_Products WHERE (stockstatus > '0' OR donotallowbackorders = 'N') AND (5 BETWEEN productsizeDOWN AND productsizeUP)AND(productmanufacturer = 'Nike' OR productmanufacturer = 'Addidas' OR productmanufacturer = 'Rebok')(hideproduct = 'N') LIMIT 0, 30

但我计划在搜索中添加更多选项。

我的主要问题很简单:我可以通过什么方式组织它以简化添加更多变量?分层 if 语句?

Travesty 一直在帮助我编写代码,并且在组织它方面真的很棒。

这是当前代码。它需要安全以防止注射。

// Database connection
$con = mysql_connect("[CENSORED]","[CENSORED]","[CENSORED]")

    or die("Could not connect: " . mysql_error());


mysql_select_db("[CENSORED]") or die('Could not select database');


// Begin organization of URL variables into MYSQL Query
$get_size = $_GET['size'];
$get_manufacturer = $_GET['manufacturer'];
$get_invisible = $_GET['invisible'];
$get_instock = $_GET['instock'];
$get_sex = $_GET['sex'];
$get_startat = $_GET['startat'];
$get_results = $_GET['results'];

if ($get_size != ""){
    $all_selectors[] = "(".$get_size." BETWEEN productsizeDOWN AND productsizeUP)"; // Add to array if size is not blank.
};

if ($get_manufacturer != ""){
    $manufacturer_exploded = explode(",", $get_manufacturer);
    $manufacturer_imploded = implode("' OR productmanufacturer = '", $manufacturer_exploded);
    $all_selectors[] = ("(productmanufacturer = '".$manufacturer_imploded."')");
};

if ($get_invisible != ""){
    $all_selectors[] = "(hideproduct = '".$get_invisible."')";
};

if($get_instock == "N" or $get_instock == "n"){
    $all_selectors[] = "(stockstatus <= '0' AND donotallowbackorders = 'Y')";
}elseif($get_instock == "Y" or $get_instock == "y") {
    $all_selectors[] = "(stockstatus > '0' OR donotallowbackorders = 'N')";
};

if ($get_startat != "" or $get_results != ""){
    $number_results = "LIMIT ".$get_startat.", ".$get_results;
} else {
    $number_results = "LIMIT 0, 15";
};

// All variables are now in an array, except "startat" and "results"
$all_selectors0 = "WHERE ".implode(" AND ", $all_selectors);

// Create SQL query

$sql="Select * FROM sadsads_Products ".$all_selectors0." ".$number_results;
4

2 回答 2

1

我会做更多这样的事情。它没有经过测试,可能不是 100% 完成...您可能需要做一些进一步的自定义,特别是在switch语句中添加更多特殊情况时,但这将使添加更多变量变得更加容易:

删除旧示例,请参阅下面的更新示例

需要注意的关键一件事是您没有清理数据库输入。您的代码容易受到 SQL 注入的攻击。我上面的示例有助于解决这个问题,但此代码尚未经过全面测试,因此您应确保在任何查询中使用之前对所有用户输入进行清理。


如果您的字段名称与您的 MySQL 列不匹配(看起来它们不匹配),那么您可以使用关联数组来修复它们:

$columns = array(
    // [form field] => [mysql column]
    'size' => 'product_size',
    'manufacturer' => 'product_manufacturer',
    'invisible' => 'hideproduct'
    // ...
);

然后在你的switch声明中,做更多这样的事情:

$whereClause[] = "{$columns[$key]} = '{$value}'";

最后更新:

记录样本- 有大量的评论和额外的东西,使它可以在键盘上工作

确切的工作代码- 您应该能够复制并粘贴它(并添加您的数据库凭据)并且它应该可以工作:

$con = mysqli_connect("[CENSORED]", "[CENSORED]", "[CENSORED]") or die("Could not connect: ". mysqli_error());
mysqli_select_db("[CENSORED]") or die("Could not select database");

$columns = array(
    'size' => 'product_size',
    'manufacturer' => 'product_manufacturer',
    'invisible' => 'hideproduct'
);

$whereClause = array();
$limit = array("startat" => 0, "results" => 15);

foreach ($_GET as $key=>$value) {
    $key = mysqli_real_escape_string($key);
    if (is_array($value)) {
        for ($i = 0; $i < count($value); $i++) {
            $value[$i] = mysqli_real_escape_string($value[$i]);
        }
    } else {
        $value = mysqli_real_escape_string($value);
    }

    switch ($key) {
        case 'size':
            $whereClause[] = "({$value} BETWEEN productsizeDOWN AND productsizeUP)";
            break;
        case 'startat':
        case 'results':
            $limit[$key] = $value;
            break;
        case 'instock':
            $whereClause[] = "(stockstatus ". ($value == 'N' ? "<=" : ">") ." '0' ". ($value == 'N' ? "AND" : "OR") ." donotallowbackorders = '". ($value == 'N' ? "Y" : "N") ."')";
            break;
        default: {
            if (is_array($value)) {
                $whereClause[] = "{$columns[$key]} IN ('". implode("', '", $value) ."')";
            } else {
                $whereClause[] = "{$columns[$key]} = '{$value}'";
            }
        }
    }
}

$sql = "SELECT * FROM ioa7pd_Products". (empty($whereClause) ? "" : " WHERE ". implode(" AND ", $whereClause)) ." LIMIT {$limit['startat']}, {$limit['results']}";
echo $sql;
于 2012-09-25T15:28:29.857 回答
0

 else {
$product_instock = "";
 };

做:

$limit = '';
if( !empty($product_limit0) && !empty($product_limit1) )
 $limit = " LIMIT $product_limit0, $product_limit1"; 

$sql="Select * FROM ioa7pd_Products WHERE ".$product_instock.$product_size."AND".$product_manufacterer_and.$product_manufacterer."".$product_invisible." $limit"; // The end result of it all. 
 echo $sql;

如果在 中有单独的参数$_GET,则必须遍历多个if语句。您可以使用数字键将参数作为数组传递给$_GET,这将有助于一堆。

于 2012-09-25T15:09:20.313 回答