Php / pdo / mysql多个DB调用最佳实践

时间:2016-07-20 14:22:36

标签: php mysql pdo

到目前为止审核我的脚本时,我意识到我使用了两种不同的方式来检索/更新数据:try/catch或多个try/catch内的多个来电,每个都有一个来电。

使用任何一种方法时,我的测试数据结果都很好,但我想修复生产环境中使用的最佳实践,因为测试数据不是现实生活。我想知道在try/catch内的多次调用中是否有可能无法获得正确的异常。

在某些脚本上,我喜欢使用open/close db使用30 try/catch进行30分贝调用,而在其他脚本上我使用open/close db进行了30分钟调用和6 try/catch

感谢。

示例方法1

try {
    $connexion = new PDO("mysql:host=$serveur;dbname=$db;charset=$charset", $login, $pwd);
    $connexion -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    select table1 / execute / process
    join table1 & table2 / execute / process
    update table3 / execute / process
    ...
    $connexion = null; // close

    } catch (PDOException $e) {
        echo "Connexion failed:".$e -> getMessage();
    }

示例方法2

try {
    $connexion = new PDO("mysql:host=$serveur;dbname=$db;charset=$charset", $login, $pwd);
    $connexion -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    select table1 / execute / process

    $connexion = null; // close

    } catch (PDOException $e) {
        echo "Connexion failed:".$e -> getMessage();
    }

try {
    $connexion = new PDO("mysql:host=$serveur;dbname=$db;charset=$charset", $login, $pwd);
    $connexion -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    join table1 & table2 / execute / process

    $connexion = null; // close

    } catch (PDOException $e) {
        echo "Connexion failed:".$e -> getMessage();
    }

try {
    $connexion = new PDO("mysql:host=$serveur;dbname=$db;charset=$charset", $login, $pwd);
    $connexion -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    update table3 / execute / process

    $connexion = null; // close

    } catch (PDOException $e) {
        echo "Connexion failed:".$e -> getMessage();
    }

更新

我知道我做错了什么(我自己学习PHP)。另一方面,我现在可以理解Shudhansh Shekhar和e4c5所做解决方案的价值。

所以我构建了一个DBaccess类,我可以看到所有优点。一个包含在脚本顶部的新实例,你几乎完成了。我测试了一个脚本,它的工作就像一个魅力。

在重新设计我的所有脚本之前,您能否验证我的代码?我不确定$this->connexion = null;是否位于关闭db的正确位置。

再次感谢您的帮助。

DBaccess.class.php

<?php
class DBaccess{
    private $serveur = "localhost";
    private $db_name = "qh61test";
    private $charset = "utf8";
    private $login = "root";
    private $pwd = "";

    private $connexion;   // dbh name
    private $erreur;
    private $requete;     // sql stmt

    public function __construct(){
        $this->connexion = null; // <-----------  NOT SURE ?
        try{
            $this->connexion = new PDO("mysql:host=" . $this->serveur . ";dbname=" . $this->db_name. ";charset=". $this->charset, $this->login, $this->pwd);
            $this->connexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
        }
        catch(PDOException $e){
            echo "Connexion foirée :".$e -> getMessage();
            // $this->erreur = $e->getMessage();
        }
    }

    public function sql($sql){
        $this->requete = $this->connexion->prepare($sql);
    }
    public function execute(){
        return $this->requete->execute();
    }
    public function resultAll(){
        $this->execute();
        return $this->requete->fetchAll(PDO::FETCH_ASSOC);
    } 
}
?>

的script.php

        <?php 
        session_start();
        include 'DBaccess.class.php';
        $db = new DBaccess();
        ...
        if (isset($_POST['periode'])) { 

            // sales within a period
            if (!empty($_POST['datebeg']) && !empty($_POST['dateend'])) {

               // datepicker dates
               $datebeg = preg_replace("([^0-9/])", "", $_POST['datebeg']);
               $dateend = preg_replace("([^0-9/])", "", $_POST['dateend']);

            $search_row = "SELECT COUNT(cmdID) as nbcmd FROM Commande2 WHERE date_cmd BETWEEN '$datebeg' AND '$dateend'"
            );

                $db->sql("$search_row"); 
                $db->execute();
                $resultat = $db->resultAll();   

            foreach($resultat as $row)
            {
           if ($row['nbcmd'] == 0) {            
                 $no_rows = "No sales for that period";
                 $all = '<div>
                    <button class="btn  btn-mini btn-primary bold" type="submit" name="all">All saless</button></div>';
                    }
            }
         }
        }

    // retrieve all sales or sales within period
    if (empty($errors) && empty($no_rows) || isset($_POST['all'])) {

    $search_tot = array(
        "select" => "SELECT COUNT(cmdID) as nbcmd, SUM(`articles_cmd`) as total_articles, SUM(`total_cmd_nofp`) as somme, AVG(`total_cmd_nofp`) as moyenne, MIN(`total_cmd_nofp`) as mini, MAX(`total_cmd_nofp`) as maxi, MIN(`date_cmd`) as date_mini, MAX(`date_cmd`) as date_maxi FROM Commande2",
        "where" => " WHERE ",
        "periode" => "date_cmd BETWEEN '$datedeb' AND '$datefin'"
    );

        if (empty($datebeg) && empty($dateend)) {
           unset($search_tot["where"],$search_tot["periode"]);
        }
    }
    $search_tot = implode(' ', $search_tot);

        // fetch all matching rows
        $db->sql("$search_tot"); 
        $db->execute();
        $resultat = $db->resultAll();   

        foreach($resultat as $row)
        {
            $date1 = date('d-m-Y', strtotime($row['date_mini']));
            $date1 = str_replace('-', '/', $date1);
            $date2 = date('d-m-Y', strtotime($row['date_maxi']));
            $date2 = str_replace('-', '/', $date2);

            $orders= '<div style="text-align: center; font-size: 16px; font-weight: bold;">Sales for '.$date1.' to '.$date2.'/div>';
             ...
        }
...

1 个答案:

答案 0 :(得分:0)

  

在某些脚本上,我有30个db调用,使用30个open / close db   尝试/捕获

但为什么呢?您只需要打开一次连接。该连接可用于多个查询,并且整整八个小时都有效!

只需删除其中一对即可。

$connexion = new PDO("mysql:host=$serveur;dbname=$db;charset=$charset",    $login, $pwd);
$connexion -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

最好还是将其移到另一个文件中,该文件包含在需要连接到数据库的每个页面中。这样,如果您的数据库设置发生变化,您只需要更改一个文件。

  

对其他人我喜欢30个db调用,6个打开/关闭数据库使用   尝试/捕获

如果您正在谈论30个查询,那么对于单个网页来说这是最不寻常的。这是您可能想要重新考虑的事情。有可能重写代码以在较少数量的查询中实现相同的目标。