Какие аргументы следует передать в PDO :: __ construct ()? - PullRequest
0 голосов
/ 28 сентября 2019

Я новичок в веб-программировании и буду просить совета для приведенного ниже кода.

У меня есть код в классе Database.Есть это.Как видите, есть соединение с базой данных с помощью MySQL.И этот код работает.

   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.Я сделал это, но что-то не так.Я пытаюсь подключить свою базу данных и получаю ошибку

Неустранимая ошибка: Uncaught 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);
           }
}

Но мой новыйкод не работаетГде проблема?

Ответы [ 2 ]

1 голос
/ 28 сентября 2019

У вашего нового класса несколько проблем.Вопрос, о котором вы спрашиваете, может быть решен путем понимания того, как правильно подключиться к PDO и что такое DSN.Для этого я должен отослать вас к этой удивительной статье https://phpdelusions.net/pdo#dsn

Возьмите этот DSN, например:

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

Вы начинаете с указания, какой драйвер БД вы хотели бы использовать: 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->pdo.

Другие примечания:

  • die(); собирается закончить весь ваш сценарий.Не используйте его.
  • Не перехватывайте исключения, просто распечатайте сообщение об ошибке.Это побеждает всю цель исключений.
  • Метод bindQueryParams() кажется совершенно ненужным.Я бы порекомендовал вам удалить его.
  • runQuery пронизан ошибками.$pdo->execute() принимает только один аргумент, который должен быть массивом значений для привязки.Нет необходимости в типе param, как в mysqli.Цикл while избыточен и некорректен.
  • num_rows не существует в PDO и не нужен вообще.
  • Ни один из этих методов не дает никаких преимуществ по сравнению с обычным PDO.

Заключение:
Написанный вами класс совершенно не нужен и только усложняет понимание и поддержку вашего кода.Хотя это могло бы иметь больше смысла с mysqli, PDO проще в использовании, и его не нужно переносить в такой класс.Пожалуйста, внимательно прочитайте статью, указанную в начале, она вам очень поможет.

0 голосов
/ 28 сентября 2019

Соединение PDO не принимает 4-й параметр для имени базы данных.Имя БД передается вместе с именем хоста.Поэтому измените:

$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->host, но для PDO, еслиэто просто путь к хосту, который вы также должны передать в используемом вами драйвере, так что вам может даже понадобиться добавить

mysql:host=

в начале этого.С mysqli это не требуется, потому что единственная поддерживаемая СУБД mysqli - это mysql.

Итак, потенциально полный ответ:

$pdo = new PDO('mysql:host=' . $this->host . ';dbname=' . $this->database, $this->user, $this->password);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...