将一堆各种请求处理到数据库中

时间:2012-09-25 15:04:54

标签: php mysql database

我目前有一个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;
    ?>

当网址为

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;

2 个答案:

答案 0 :(得分:1)

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

  

删除旧示例,见下面的更新示例

需要注意的一件事是,您没有清理数据库输入。您的代码容易受到SQL注入攻击。我上面的例子有助于解决这个问题,但是这段代码没有经过全面测试,所以在任何查询中使用它之前,你应该确保所有用户输入都已经过清理。

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

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

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

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

最终更新:

DOCUMENTED SAMPLE - 有足够的评论和额外的东西让它在Codepad上运行

完整的工作代码 - 你应该能够复制并粘贴它(并添加你的数据库凭据),它应该可以工作:

$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;

答案 1 :(得分: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语句。你可以使用数字键将params作为数组传递给$_GET,这样可以帮助很多人。