Php/pdo/mysql多数据库调用最佳实践
到目前为止,在查看我的脚本时,我意识到我使用了两种不同的方法来检索/更新数据:在一个Php/pdo/mysql多数据库调用最佳实践,php,mysql,pdo,Php,Mysql,Pdo,到目前为止,在查看我的脚本时,我意识到我使用了两种不同的方法来检索/更新数据:在一个try/catch中进行多次调用,或者每次调用一个try/catch 使用这两种方法时,测试数据的结果看起来都不错,但我希望确定在生产环境中使用的最佳实践,因为测试数据不是真实的。例如,我想知道在try/catch中的多个调用中是否有可能无法获得正确的异常 在一些脚本中,我使用try/catch调用30个open/close db,在其他脚本中,我使用try/catch调用6个open/close db,调用30
try/catch
中进行多次调用,或者每次调用一个try/catch
使用这两种方法时,测试数据的结果看起来都不错,但我希望确定在生产环境中使用的最佳实践,因为测试数据不是真实的。例如,我想知道在try/catch
中的多个调用中是否有可能无法获得正确的异常
在一些脚本中,我使用try/catch
调用30个open/close db
,在其他脚本中,我使用try/catch
调用6个open/close db
,调用30个db
谢谢
示例方法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代码>位于关闭数据库的正确位置
再次感谢你的帮助
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);
}
}
?>
<?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>';
...
}
...
script.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);
}
}
?>
<?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>';
...
}
...
在一些脚本中,我有30个db调用,其中30个使用
尝试/抓住
但是为什么呢?您只需要打开一次连接。这个连接可以用于许多查询,并且可以使用整整八个小时
只需删除除一对之外的所有对
$connexion = new PDO("mysql:host=$serveur;dbname=$db;charset=$charset", $login, $pwd);
$connexion -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
最好还是把它移到另一个文件中,在需要连接到数据库的每个页面中都包含这个文件。这样,如果数据库设置发生更改,则只需更改一个文件
在其他人身上,我有30个db调用,使用6个打开/关闭db
试试看
如果你说的是30个查询,这对于一个网页来说是最不寻常的。这是你可能需要重新考虑的事情。也许可以重写代码,在更少的查询中实现相同的目标
在一些脚本中,我有30个db调用,其中30个使用
尝试/抓住
但是为什么呢?您只需要打开一次连接。这个连接可以用于许多查询,并且可以使用整整八个小时
只需删除除一对之外的所有对
$connexion = new PDO("mysql:host=$serveur;dbname=$db;charset=$charset", $login, $pwd);
$connexion -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
最好还是把它移到另一个文件中,在需要连接到数据库的每个页面中都包含这个文件。这样,如果数据库设置发生更改,则只需更改一个文件
在其他人身上,我有30个db调用,使用6个打开/关闭db
试试看
如果你说的是30个查询,这对于一个网页来说是最不寻常的。这是你可能需要重新考虑的事情。可以重写代码,在更少的查询中实现相同的目标。为什么不创建一个DB处理程序类,以便。。。。。。。您只需使用一行代码$this->db即可使用calm编写代码。如果这些查询继续增长,我担心您会烧掉数据库MySQL的连接协议不是特别“重”,但每次连接/执行/断开连接都会浪费资源。它还使得执行诸如多查询事务、保留服务器端变量等操作变得不可能。。。因为每次您断开连接时,所有这些都会被销毁/清理。@Marc B-完全同意,每次呼叫后关闭连接时,一次又一次地声明变量是一件痛苦的事情。谢谢。@Shudhansh Shekhar-我也担心我的cpu会融化:)请参阅更新。谢谢。为什么不创建一个DB处理程序类以便。。。。。。。您只需使用一行代码$this->db即可使用calm编写代码。如果这些查询继续增长,我担心您会烧掉数据库MySQL的连接协议不是特别“重”,但每次连接/执行/断开连接都会浪费资源。它还使得执行诸如多查询事务、保留服务器端变量等操作变得不可能。。。因为每次您断开连接时,所有这些都会被销毁/清理。@Marc B-完全同意,每次呼叫后关闭连接时,一次又一次地声明变量是一件痛苦的事情。谢谢。@Shudhansh Shekhar-我也担心我的cpu会融化:)请参阅更新。谢谢。既然他只发布了select table1/execute/process join table1&table2/execute/process update table3/execute/process
@shudhanshekharatletlast告诉他如何重用连接,我该怎么办。我想那可能够了。@e4c5-谢谢你的回复。事实上,我给出了我在最初几天里写的最差的脚本示例(从那以后就被拆分了)。平均每个脚本调用3/4 db以上。这更像是一个获得正确方向的一般例子。请参阅更新。谢谢。既然他只发布了select table1/execute/process join table1&table2/execute/process update table3/execute/process
@shudhanshekharatletlast告诉他如何重用连接,我该怎么办。我想那可能够了。@e4c5-谢谢你的回复。事实上,我给出了我在最初几天里写的最差的脚本示例(从那以后就被拆分了)。平均每个脚本调用3/4 db以上。这更像是一个获得正确方向的一般例子。请参阅更新。谢谢