如何避免重复大量的php准备12次以上

时间:2017-06-13 03:27:50

标签: php mysqli

try  {$db=mysqli_connect( etc )
catch {
        retry on time out
        handle errors
}

try { if (!($errors = $db->prepare("insert into errors (`insert`,`error`) values(?,?);
    print "\n*********prepare Error:" . $db->error;
}
}
catch { repeat above}

try {$errors->bind_param("ss",$sqlLoad,$errormsg); }
catch {repeat above)
....
try {$error->execute()} catch {repeat above error handling}

现在对不同字段的不同SQL查询重复所有这些10-40次。

这是很多重复的代码。使我的代码难以阅读,如果有人想添加更多的SQL查询,他们就不得不重复大量的代码。

我在想这样的事情,但遇到了绑定的绊脚石。

$sql[0]=array("name","select ? from <tablename>","s");
$sql[1]=array("name","select ?,? from <tablename>","ss");
$sql[2]=array("name","select ?,?,? from <tablename>","sss");
$sql[3]=array("name","select ?,?,?,? from <tablename>","ssss");

for(i=0;i<=3,i++){
try (
$preQuery[$sql[i][0]=$db->prepare($sql[i][1]);}
catch {}
try {$preQuery[$sql[i][0]]->bind_param($sql[i][2],????);}  //Here is the trouble how do I define unique variables
catch {   }
}

这是一些真实的代码 这是一项正在进行的工作

foreach ($fieldspath as $field)
{
$filepath=$_SERVER[$field];
$result=$queryfile->execute();
$getres = $queryfile->get_result();
$numRows = -1;
$numRows = $getres->num_rows;

    if ($numRows <>0)
    {
      $qryField = $getres->fetch_assoc();
      $_SERVER[$field]=$qryField["id"];
      $fileCount=$qryField["count"];
      $fileRating=$qryField["rating"];
      mysqli_query($db, "update Files set count=count+1 where `id` ='" . $qryField["id"] . "';");
      continue;
    }
    else
    {
    $output = $insertFile->execute();
    $result = $queryip->execute();
    $getres = $queryip->get_result();
    $qryField = $getres->fetch_assoc();
    $_SERVER[$field]=$qryField["id"];
    }

}

注意:如何通过以下方式重新执行查询: $结果= $ queryfile-&GT;执行();

不必重新说明查询,参数也不需要。一切都是自动的。实际的查询都列在程序的顶部,我永远不必看到它们,或者再次重述它们。在使用它们之前,我不需要将参数填充到数组中。

<?php
$pipeName = '/var/run/mysql/mysql.sock';
$username = 'user';
$password = 'password';
$db = new PDO('mysql:unix_socket='.$pipeName.";dbname=dbase", $username, $password);

$sql["errors"]="insert into errors (`insert`,`error`) values(:insert,:error);";
$sql["events"]="insert into event (`message`) values(?);";
$sql["queryip"]="select id,count,rating FROM ip where address=? limit 1;";
$sql["queryUsrAgent"]="select id,count,rating  FROM http_user_agent where agent=? limit 1;";
$sql["insUsrAgent"]="insert into http_user_agent (`agent`) values (?);";
$sql["insertIP"]="insert into ip (`address`) values (?);";
$sql["insertReqURI"]="insert into request (`REQUEST_URI`) values (?);";
$sql["queryReqURI"]="select * FROM request where REQUEST_URI=? LIMIT 1;";
$sql["queryfile"]="select id,count,rating FROM Files where path=? limit 1;";
$sql["insertFile"]="insert into Files (`path`) values (?);";
$sql["cntIp"]="update ip set count=count+1 where `address` = :ip";
$sql["cntFiles"]="update Files set count=count+1 where `id` = :id;";
$sql["cntAgent"]="update http_user_agent set count=count+1 where `agent` = :agent;";
$sql["reqRequest"]="select *  FROM request where REQUEST_URI= :requesturi LIMIT 1;";
$sql["cntRequest"]="update request set count=count+1 where `REQUEST_URI` = :requesturi;";

$ready=doPrepare($db,$sql);

$ready["errors"]->execute(array("insert"=>"stuff","error" =>"stuff"));
pdoRun($ready,"errors",array("iniisert"=>"iiiii","error" =>"yyyyyggg"));

function doPrepare($db, $enmass) {
    foreach ($enmass as $key => $sql) {
    try {
         $stmt[$key] = $db->prepare($sql);
     } catch (PDOException $e) {
        print "\nStuff";
        trigger_error($e);
        return false;
    }
    }
    return $stmt;
}

function pdoRun($ready,$query,$vals) {
    try {
          $ready[$query]->execute($vals);
        } catch (PDOException $e) {
        print "\nExecution fail";
        }

}

//       $stmt->execute(array_values($column_values));


?>

1 个答案:

答案 0 :(得分:0)

像你一样做准备好的查询并不像你认为的那样有效。参数占位符只能替换文字值。您不能将它们用于列名或表名或其他任何内容。

您也无法准备"select ? from"之类的查询,因为它不会命名表格。这不是语法上完整的查询。

更好的做法是编写一个“辅助函数”,为您做好准备和执行。你可以通过这种方式减少重复代码。

顺便说一句,我发现在编写像这样的辅助函数时,PDO比Mysqli容易得多,因为你不必使用带有变量参数的bind_param()。在PDO中,您只需将一组参数传递给execute()

function doInsert($db, $sql, $params) {
    try {
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
    } catch (PDOException $e) {
        trigger_error($e);
        return false;
    }
    return true;
}

现在这样称呼它:

$sql = "insert into errors (`insert`, `error`) values(?, ?)";
$success = doInsert($db, $sql, [$sqlLoad, $errormsg]);

您甚至可能希望为您设置格式化INSERT语句的函数:

function doInsert($db, $table, $column_values) {
    $placeholders = array_fill(1, count($column_values), '?');
    $columns = implode(',', array_keys($column_values));
    $sql = "INSERT INTO `$table` ($columns) VALUES ($placeholders)";
    try {
        $stmt = $db->prepare($sql);
        $stmt->execute(array_values($column_values));
    } catch (PDOException $e) {
        trigger_error($e);
        return false;
    }
    return true;
}

然后这样称呼:

$success = doInsert($db, "errors", ["insert"=>$sqlLoad, "error"=>$errormsg]);

您还必须做一些事情来对列名称应用反向标记。