【问题标题】:What arguments should be passed to PDO::__construct()?应该将哪些参数传递给 PDO::__construct()?
【发布时间】:2020-01-28 13:33:37
【问题描述】:

我是网络编程的新手,想请教以下代码。

我在类数据库中有代码。有它。如您所见,使用 mysqli 连接到数据库。并且这段代码有效。

   function __construct() {
        $this->conn = $this->connectDB();
    }

    function connectDB() {
        $conn = mysqli_connect($this->host,$this->user,$this->password,$this->database);
        return $conn;
    }

    function runBaseQuery($query) {
        $result = mysqli_query($this->conn,$query);
        while($row=mysqli_fetch_assoc($result)) {
            $resultset[] = $row;
        }
        if(!empty($resultset))
            return $resultset;
    }



    function runQuery($query, $param_type, $param_value_array) {
        $sql = $this->conn->prepare($query);
        $this->bindQueryParams($sql, $param_type, $param_value_array);
        $sql->execute();
        $result = $sql->get_result();
            if ($result->num_rows > 0) {
            while($row = $result->fetch_assoc()) {
                $resultset[] = $row;
            }
        }
            if(!empty($resultset)) {
            return $resultset;
        }
    }

    function bindQueryParams($sql, $param_type, $param_value_array) {
        $param_value_reference[] = & $param_type;
        for($i=0; $i<count($param_value_array); $i++) {
            $param_value_reference[] = & $param_value_array[$i];
        }
        call_user_func_array(array(
            $sql,
            'bind_param'
        ), $param_value_reference);
    }

    function insert($query, $param_type, $param_value_array) {
        $sql = $this->conn->prepare($query);
        $this->bindQueryParams($sql, $param_type, $param_value_array);
        $sql->execute();
    }

    function update($query, $param_type, $param_value_array) {
        $sql = $this->conn->prepare($query);
        $this->bindQueryParams($sql, $param_type, $param_value_array);
        $sql->execute();
    }

我必须在 PDO 中编写这个类。我已经做到了,但是有问题。我尝试连接我的数据库并收到错误

致命错误:未捕获的 TypeError:PDO::__construct() 需要参数 4

class DB {
    private $host = "";
    private $user = "";
    private $password = "";
    private $database = "";
    private $pdo;


    function __construct() {
        $this->pdo = $this->connectDB();
    }

    function connectDB() {
        try
        {
            $pdo = new PDO($this->host,$this->user,$this->password,$this->database);
        }
        catch (PDOException $e) {
            print "Error!: " . $e->getMessage();
        }
        die();
    }

    function runBaseQuery($query)
    {
        $result = $pdo->query($query);
        while ($row = $pdo->fetch(PDO::FETCH_ASSOC)) {
            $resultset[] = $row;
        }
        if (!empty($resultset))
            return $resultset;
    }



    function runQuery($query, $param_type, $param_value_array) {

        $sql = $pdo->prepare($query);
        $pdo->execute($sql, $param_type, $param_value_array);
        $result = $pdo->fetchAll(PDO::FETCH_ASSOC);

        if ($result->num_rows > 0) {
            while ($row = $pdo->fetchAll(PDO::FETCH_ASSOC)) {
                $resultset[] = $row;
            }
        }
        if(!empty($resultset)) {
            return $resultset;
        }
    }

    function bindQueryParams($sql, $param_type, $param_value_array) {
        $param_value_reference[] = & $param_type;
        for($i=0; $i<count($param_value_array); $i++) {
            $param_value_reference[] = & $param_value_array[$i];
        }
        call_user_func_array(array(
            $sql,
            'bind_param'
        ), $param_value_reference);
    }

    function insert($query, $param_type, $param_value_array) {
        $sql = $pdo->prepare($query);
        $pdo->execute($sql, $param_type, $param_value_array);
           }

    function update($query, $param_type, $param_value_array) {
        $sql = $pdo->prepare($query);
        $pdo->execute($sql, $param_type, $param_value_array);
           }
}

但是我的新代码不起作用。问题出在哪里?

【问题讨论】:

  • 你试过调试脚本吗?传递给new PDO($this-&gt;host,$this-&gt;user,$this-&gt;password,$this-&gt;database) 行的参数的值是多少?
  • 请看如何正确编写类似`runBaseQuery`的函数:phpdelusions.net/pdo/pdo_wrapper
  • 谢谢!建议使用类似 `runBaseQuery` 的函数帮助我

标签: php class pdo


【解决方案1】:

您的新课程有多个问题。您所问的问题可以通过了解如何与 PDO 正确连接以及 DSN 是什么来解决。为此,我必须向您推荐这篇很棒的文章https://phpdelusions.net/pdo#dsn

以这个 DSN 为例:

      mysql:host=localhost;dbname=test;port=3306;charset=utf8mb4
driver^    ^ colon         ^param=value pair    ^semicolon 

首先指定要使用的 DB 驱动程序:mysql:。之后是一个以分号分隔的键值对列表。顺序应该是主机、数据库名称和字符集。您应该指定所有这些值。

您的 DSN 是PDO::__construct() 的第一个参数,第二个和第三个分别是用户名和密码。第三个是选项数组。

您的选项数组应至少包含两个值。您需要启用错误报告并关闭模拟的准备好的语句。这些是推荐的设置。

您的连接应该至少类似于:

$options = [
    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
    \PDO::ATTR_EMULATE_PREPARES => false,
];
$this->pdo = new PDO('mysql:host='.$this->host.';dbname='.$this->database.';charset=utf8mb4', $this->user, $this->password, $options);

但是,请注意,构造函数将被调用一次,您不需要将这些值放在私有属性中。它们可以简单地是常量或在构造函数中硬编码。打开连接后,您将永远不需要重用此值。

您的第二个主要错误是您在很多地方都引用了$pdo,但您应该使用$this-&gt;pdo

其他说明:

  • die(); 将结束你的整个脚本。不要使用它。
  • 不要捕获异常,只是为了打印出错误信息。它违背了例外的全部目的。
  • bindQueryParams() 方法似乎完全没有必要。我建议你删除它。
  • runQuery 充满了错误。 $pdo-&gt;execute() 只接受一个参数,它应该是要绑定的值数组。不需要像 mysqli 中那样的参数类型。 while 循环是多余且不正确的。
  • num_rows 在 PDO 中不存在,根本不需要。
  • 这些方法都没有比单纯的 PDO 带来任何好处。

结论:
您编写的类是完全没有必要的,只会使您的代码更难理解和维护。虽然使用 mysqli 可能更有意义,但 PDO 更易于使用,并且不需要包装在此类中。请仔细阅读开头链接的文章,它将对您有很大帮助。

【讨论】:

    【解决方案2】:

    PDO 连接不采用第四个参数作为数据库名称。 DB 名称与主机名一起传入。所以改变:

    $pdo = new PDO($this->host,$this->user,$this->password,$this->database);
    

    到:

    $pdo = new PDO($this->host . ';dbname=' . $this->database, $this->user, $this->password);
    

    欲了解更多信息,请参阅https://www.php.net/manual/en/pdo.connections.php

    此外,尚不清楚$this-&gt;host 包含什么,但对于 PDO,如果这只是您需要传入正在使用的驱动程序的主机路径,那么您甚至可能需要添加

    mysql:host=
    

    到此开始。对于mysqli,这不是必需的,因为mysqli 支持的唯一RDBMS 是mysql

    所以可能是完整的答案:

    $pdo = new PDO('mysql:host=' . $this->host . ';dbname=' . $this->database, $this->user, $this->password);
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    • 2012-08-09
    • 1970-01-01
    相关资源
    最近更新 更多