<i id='m72e1'><tr id='m72e1'><dt id='m72e1'><q id='m72e1'><span id='m72e1'><b id='m72e1'><form id='m72e1'><ins id='m72e1'></ins><ul id='m72e1'></ul><sub id='m72e1'></sub></form><legend id='m72e1'></legend><bdo id='m72e1'><pre id='m72e1'><center id='m72e1'></center></pre></bdo></b><th id='m72e1'></th></span></q></dt></tr></i><div id='m72e1'><tfoot id='m72e1'></tfoot><dl id='m72e1'><fieldset id='m72e1'></fieldset></dl></div>

    1. <tfoot id='m72e1'></tfoot>

        <small id='m72e1'></small><noframes id='m72e1'>

        • <bdo id='m72e1'></bdo><ul id='m72e1'></ul>

        <legend id='m72e1'><style id='m72e1'><dir id='m72e1'><q id='m72e1'></q></dir></style></legend>
      1. 简单的 PDO 包装器

        时间:2023-09-20

        <small id='g0T4n'></small><noframes id='g0T4n'>

          <bdo id='g0T4n'></bdo><ul id='g0T4n'></ul>

          1. <legend id='g0T4n'><style id='g0T4n'><dir id='g0T4n'><q id='g0T4n'></q></dir></style></legend>

              • <tfoot id='g0T4n'></tfoot>

                    <tbody id='g0T4n'></tbody>
                  <i id='g0T4n'><tr id='g0T4n'><dt id='g0T4n'><q id='g0T4n'><span id='g0T4n'><b id='g0T4n'><form id='g0T4n'><ins id='g0T4n'></ins><ul id='g0T4n'></ul><sub id='g0T4n'></sub></form><legend id='g0T4n'></legend><bdo id='g0T4n'><pre id='g0T4n'><center id='g0T4n'></center></pre></bdo></b><th id='g0T4n'></th></span></q></dt></tr></i><div id='g0T4n'><tfoot id='g0T4n'></tfoot><dl id='g0T4n'><fieldset id='g0T4n'></fieldset></dl></div>

                1. 本文介绍了简单的 PDO 包装器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  我的 Web 应用程序目前确实执行了简单的查询:简单的 CRUD 操作、计数、...

                  My web application currently has do execute simple queries: simple CRUD operations, counting,...

                  几个月前,有人推荐我在这里为此编写一个简单的 PDO 包装器(以避免每次应执行查询时编写 try/catch、prepare()、execute() 等).显示了此示例方法(我进行了一些更改,以便可以在我自己的项目中使用它):

                  A few months ago, someone recommended me here to write a simple PDO wrapper for this (to avoid writing try/catch, prepare(), execute(), etc. each time a query should be executed). This example method was shown (I've made some changes so I could use it in my own project):

                  public function execute() {
                      $args  = func_get_args();
                      $query = array_shift($args);
                      $result = false;
                  
                      try {
                        $res = $this->pdo->prepare($query);
                        $result = $res->execute($args);
                      } catch (PDOException $e) { echo $e->getMessage(); }
                  
                      return $result;
                    }
                  

                  由于我需要执行更多操作(执行查询、检索 1 条记录、检索多条记录、计算结果),我为所有这些操作创建了一个方法:

                  As I need to perform more operations (executing queries, retrieving 1 record, retrieving multiple records, counting results) I created a method for all of these:

                    public function getMultipleRecords() {
                      $args  = func_get_args();
                      $query = array_shift($args);
                      $records = array();
                  
                      try {
                        $res = $this->pdo->prepare($query);
                        $res->execute($args);
                        $records = $res->fetchAll();
                      } catch (PDOException $e) { echo $e->getMessage(); }
                  
                      return $records;
                    }
                  
                    public function getSingleRecord() {
                      $args  = func_get_args();
                      $query = array_shift($args);
                      $record = array();
                  
                      try {
                        $res = $this->pdo->prepare($query);
                        $res->execute($args);
                        $record = $res->fetch();
                      } catch (PDOException $e) { echo $e->getMessage(); }
                  
                      return $record;
                    }
                  
                    public function execute() {
                      $args  = func_get_args();
                      $query = array_shift($args);
                      $result = false;
                  
                      try {
                        $res = $this->pdo->prepare($query);
                        $result = $res->execute($args);
                      } catch (PDOException $e) { echo $e->getMessage(); }
                  
                      return $result;
                    }
                  
                    public function count() {
                      $args  = func_get_args();
                      $query = array_shift($args);
                      $result = -1;
                  
                      try {
                        $res = $this->pdo->prepare($query);
                        $res->execute($args);
                        $result = $res->fetchColumn();
                      } catch(PDOException $e) { echo $e->getMessage(); }
                  
                      return $result;
                    }
                  

                  如您所见,大部分代码是相同的.每种方法只有 2 行代码不同:$result 的初始化(我总是想返回一个值,即使查询失败)和获取.我可以不使用 4 种方法,而是只编写其中一种并传递一个带有操作类型的额外参数.这样,我可以使用 switch 语句的一堆 if/else 语句.但是,我认为代码可能会变得混乱.这是解决这个问题的好方法吗?如果没有,有什么好的解决办法?

                  As you see, most of the code is the same. Only 2 lines of code are different for each method: the initialisation of $result (I always want to return a value, even if the query fails) and the fetching. Instead of using 4 methods, I could write just one of them and pass an extra parameter with the type of action. That way, I could use a bunch of if/else statements of a switch statement. However, I think the code can get messy. Is this a good way for solving this problem? If not, what would be a good solution to it?

                  我遇到的第二个问题(这就是我现在正在研究这个类的原因)是我想将准备好的语句与 LIMIT SQL 语句一起使用.但是,这是不可能的:

                  The second problem I have (which is why I'm working on this class right now) is that I want to use prepared statements with the LIMIT SQL statement. However, it is not possible to do this:

                  $res = $pdo->prepare("SELECT * FROM table LIMIT ?");
                  $res->execute(array($int));
                  

                  由于某种原因,变量将被引用(因此查询将失败),如下所述:https://bugs.php.net/bug.php?id=40740

                  The variabele will be quoted for some reason (and so the query will fail), as explained here: https://bugs.php.net/bug.php?id=40740

                  解决方案似乎使用 bindValue() 并使用 int 数据类型作为参数:http://www.php.net/manual/de/pdostatement.bindvalue.php

                  The solution seems to use bindValue() and use the int datatype as a parameter: http://www.php.net/manual/de/pdostatement.bindvalue.php

                  我可以重写方法来支持这一点,但我还需要使用一个额外的参数.我不能再使用 $db->e​​xecute($sql, $variable1, $variable2); 因为我需要知道数据类型.

                  I could rewrite the method(s) to support this, but I would also need to use an extra parameter. I can't just use $db->execute($sql, $variable1, $variable2); anymore as I need to know the data type.

                  解决这个问题的最佳方法是什么?

                  What's the best way to solve this?

                  谢谢

                  推荐答案

                  如何使用可以链接的方法创建一个类(为了清楚起见,我已经删除了错误检查):

                  How about creating a class with methods that you can chain (for clarity, I've removed error checking):

                  class DB {
                  
                      private $dbh;
                      private $stmt;
                  
                      public function __construct($user, $pass, $dbname) {
                          $this->dbh = new PDO(
                              "mysql:host=localhost;dbname=$dbname",
                              $user,
                              $pass,
                              array( PDO::ATTR_PERSISTENT => true )
                          );
                      }
                  
                      public function query($query) {
                          $this->stmt = $this->dbh->prepare($query);
                          return $this;
                      }
                  
                      public function bind($pos, $value, $type = null) {
                  
                          if( is_null($type) ) {
                              switch( true ) {
                                  case is_int($value):
                                      $type = PDO::PARAM_INT;
                                      break;
                                  case is_bool($value):
                                      $type = PDO::PARAM_BOOL;
                                      break;
                                  case is_null($value):
                                      $type = PDO::PARAM_NULL;
                                      break;
                                  default:
                                      $type = PDO::PARAM_STR;
                              }
                          }
                  
                          $this->stmt->bindValue($pos, $value, $type);
                          return $this;
                      }
                  
                      public function execute() {
                          return $this->stmt->execute();
                      }
                  
                      public function resultset() {
                          $this->execute();
                          return $this->stmt->fetchAll();
                      }
                  
                      public function single() {
                          $this->execute();
                          return $this->stmt->fetch();
                      }
                  }
                  

                  然后您可以像这样使用它:

                  You can then use it like this:

                  // Establish a connection.
                  $db = new DB('user', 'password', 'database');
                  
                  // Create query, bind values and return a single row.
                  $row = $db->query('SELECT col1, col2, col3 FROM mytable WHERE id > ? LIMIT ?')
                     ->bind(1, 2)
                     ->bind(2, 1)
                     ->single();
                  
                  // Update the LIMIT and get a resultset.
                  $db->bind(2,2);
                  $rs = $db->resultset();
                  
                  // Create a new query, bind values and return a resultset.
                  $rs = $db->query('SELECT col1, col2, col3 FROM mytable WHERE col2 = ?')
                     ->bind(1, 'abc')
                     ->resultset();
                  
                  // Update WHERE clause and return a resultset.
                  $db->bind(1, 'def');
                  $rs = $db->resultset();
                  

                  如果您愿意,您可以更改 bind 方法以接受数组或关联数组,但我发现此语法非常清晰 - 它避免了必须构建数组.参数类型检查是可选的,因为 PDO::PARAM_STR 适用于大多数值,但请注意传递空值时的潜在问题(请参阅 PDOStatement->bindValue 文档中的注释).

                  You could alter the bind method to accept an array or associative array if you prefer, but I find this syntax quite clear - it avoids having to build an array. The parameter type checking is optional, as PDO::PARAM_STR works for most values, but be aware of potential issues when passing null values (see comment in PDOStatement->bindValue documentation).

                  这篇关于简单的 PDO 包装器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:PHP Mysql PDO 绑定变量数量与令牌数量不匹配 下一篇:为什么在 PHP 和 MySQL 中使用 PDO 的某些类型的准备

                  相关文章

                  最新文章

                  <i id='zqML4'><tr id='zqML4'><dt id='zqML4'><q id='zqML4'><span id='zqML4'><b id='zqML4'><form id='zqML4'><ins id='zqML4'></ins><ul id='zqML4'></ul><sub id='zqML4'></sub></form><legend id='zqML4'></legend><bdo id='zqML4'><pre id='zqML4'><center id='zqML4'></center></pre></bdo></b><th id='zqML4'></th></span></q></dt></tr></i><div id='zqML4'><tfoot id='zqML4'></tfoot><dl id='zqML4'><fieldset id='zqML4'></fieldset></dl></div>

                  1. <small id='zqML4'></small><noframes id='zqML4'>

                    <tfoot id='zqML4'></tfoot>
                        <bdo id='zqML4'></bdo><ul id='zqML4'></ul>

                    1. <legend id='zqML4'><style id='zqML4'><dir id='zqML4'><q id='zqML4'></q></dir></style></legend>