避免MySQL查询的代码重复(多次)

时间:2017-02-13 12:05:15

标签: php mysql

我有以下代码:

<?php
include_once "connect.php";

$question_01 = mysqli_real_escape_string($con, $_POST['question_01']);
// $question_02 - $question_09 go here...
$question_10 = mysqli_real_escape_string($con, $_POST['question_10']);

    $i = 0;
    $array_sum=[];
     while ($i < 10){
      $i++;
       $sql =  "SELECT * FROM parteners WHERE question_no = 1 AND answer_variant = '$question_01'";
       $result = mysqli_query($con, $sql);

       $final_array_1 = array();

      while ($row = mysqli_fetch_array($result, MYSQLI_NUM))
      {

        $final_array_1 = $row;
            $array_sum = array_map(function () {
                return array_sum(func_get_args());
            }, $array_sum, $final_array_1);
      }
}
print_r($final_array_1);

如您所见,我需要为每个$ question _ ##重复代码。除了重复代码之外,还有更聪明的方法吗?我不仅关心将所有东西都变成代码意大利面而且还关注操作效率和装载时间。

如果您需要澄清,请告诉我。

更新:基本上它应该增加查询中“question_no”的值,直到它达到10并为每个问题选择相应的$ _POST值。

3 个答案:

答案 0 :(得分:1)

有两种方式,变量变量或数组。我建议使用数组,因为它们不容易在任何地方抛出错误。

<?php
include_once "connect.php";
$questions = array();
$questions[1] = mysqli_real_escape_string($con, $_POST['question_01']);
// $question_02 - $question_09 go here...
$questions[10] = mysqli_real_escape_string($con, $_POST['question_10']);

    $i = 0;
    $array_sum=[];
     while ($i < 10){
      $i++;
       $sql =  "SELECT * FROM parteners WHERE question_no = $i AND answer_variant = '".$questions[$i]."'";
       $result = mysqli_query($con, $sql);

       $final_array_1 = array();

      while ($row = mysqli_fetch_array($result, MYSQLI_NUM))
      {

        $final_array_1 = $row;
            $array_sum = array_map(function () {
                return array_sum(func_get_args());
            }, $array_sum, $final_array_1);
      }
}
print_r($final_array_1);
编辑:我使用数组而不是直接使用while循环中的POST变量的原因是在运行任何验证之前有空间(确保你的问题数组包含10个发布值等)

答案 1 :(得分:1)

首先,为了使您的代码更加现代和高效,您应该使用 PHP 数据对象,简称PDO。您将有机会准备 这些语句完全是为了这个:你构建一个查询 “模板”并使用不同的数据执行,非常有效和安全。

循环是正确的方法。此外,您的$questions数组是一个 因为您可以从内部$_POST检索数据,所以这是不必要的 你的循环。但如果你想使用它,就没有必要“逃避”了 数据库的字符串,因为它由PDO处理。所以你可以建立 您的阵列更容易:

$questions = [
    $_POST['question_01'],
    $_POST['question_02'],
    $_POST['question_03'],
    # ...
    $_POST['question_10'],
];

你的PDO循环:

$dbh = ... # create your database handle, connect to it
$st = $dbh->prepare("
    SELECT * FROM parteners
    WHERE question_no = ? AND answer_variant = ?;
");

foreach (range(1, 10) as $i) {

    $result = $st->execute([ $i, $questions[$i-1] ]);
    # or, to build directly
    $result = $st->execute([
        $i, $_POST[ sprintf("question_%02d", $i) ]
    ]);

    $final_array[] = $result->fetchAll(PDO::FETCH_NUM);

}

print_r($final_array);

答案 2 :(得分:1)

我会构建一个包含所有问题和anwsers的SQL语句,并使用编程逻辑完成剩下的工作。循环中的SQL查询是一个坏主意,因为您必须为完成任务而花费大量开销,数据库服务器可以做得更好。您还应该使用预准备语句来提高性能和安全性。

$query = "SELECT * FROM parteners WHERE (question_no = 1 AND answer_variant = ?) OR (question_no = 2 AND answer_variant = ?) OR (question_no = 3 AND answer_variant = ?) OR (question_no = 4 AND answer_variant = ?) OR (question_no = 5 AND answer_variant = ?) OR (question_no = 6 AND answer_variant = ?) OR (question_no = 7 AND answer_variant = ?) OR (question_no = 8 AND answer_variant = ?) OR (question_no = 9 AND answer_variant = ?) OR (question_no = 10 AND answer_variant = ?)" 
$stmt = myqli_prepare($query);
mysqli_stmt_bind_param($stmt, 'ssssssssss', $question_01, $question_02, $question_03,.....);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);