Мне нужно преобразовать все PDO в моей функции в MYSQLI, но я не могу найти альтернативы PDO - PullRequest
1 голос
/ 13 февраля 2020

Я пытаюсь найти способ убедить мой PDO :: PARAM_INT и другие значения pdo в инструкции switch ниже использовать mysqli. Я делаю портфельный проект для школы и узнал, что нам по какой-то причине запрещено использовать PDO, поэтому теперь мне нужно реструктурировать 10 страниц. Заранее спасибо!

public function bind($param, $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($param, $value, $type);
}

Ответы [ 2 ]

2 голосов
/ 13 февраля 2020

mysqli имеет метод с именем bind_param(). Он работает совсем по-другому, поэтому заменить код на него не так просто. Первый параметр, переданный bind_param(), представляет собой строку, состоящую из букв, обозначающих тип параметров. По большей части вы можете использовать s для всех типов. В вашем случае вам, вероятно, потребуется отобразить логические значения на целые числа. MySQL не имеет истинного логического типа данных, поэтому все логические значения сохраняются как 0 или 1.

Пример может выглядеть следующим образом:

$int = 2;
$bool = (int) false;
$string = '0';

$stmt = $mysqli->prepare('INSERT INTO dates VALUES(?,?,?)');
$stmt->bind_param('sss', $int, $bool, $string);
$stmt->execute();

Все параметры должны быть связаны в одиночный вызов bind_param и переменные должны передаваться по ссылке, чтобы они не могли быть литералами.

Вы не можете просто заменить свой метод на mysqli-эквивалент. Вам нужно было бы переписать ваш код logi c. Я настоятельно рекомендую придерживаться PDO; это проще и лучше, чем MySQL. Если вы должны использовать mysqli, то вы должны написать или использовать существующий класс абстракции базы данных. Использование mysqli само по себе не рекомендуется.

Это пример того, как может выглядеть такой класс:

class DBClass extends mysqli {
    public function __construct(
        $host = null,
        $username = null,
        $passwd = null,
        $dbname = null,
        $port = null,
        $socket = null
    ) {
        mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
        parent::__construct($host, $username, $passwd, $dbname, $port, $socket);
        $this->set_charset('utf8mb4');
    }

    public function safeQuery(string $sql, array $params = []): ?array {
        $stmt = $this->prepare($sql);
        if ($params) {
            $stmt->bind_param(str_repeat("s", count($params)), ...$params);
        }
        $stmt->execute();
        if ($result = $stmt->get_result()) {
            return $result->fetch_all(MYSQLI_BOTH);
        }
        return null;
    }
}

$int = 2020;
$bool = false;
$string = '0';

$conn = new DBClass('localhost', 'inet', '5432', 'test');
$conn->safeQuery('INSERT INTO dates VALUES(?,?,?)', [$int, (int) $bool, $string]);

var_dump($conn->safeQuery('SELECT * FROM dates WHERE year=2020'));

Это не самый лучший класс за всю историю, но я использую его, чтобы проиллюстрировать, как можно go о расширение mysqli с помощью более простого вспомогательного метода. Он имеет тот же конструктор, что и класс mysqli, но конструктор включает отчеты об ошибках и устанавливает правильную кодировку. Новый метод является просто оберткой вокруг громоздкого шаблона prepare / bind / execute. Это должно работать для всех видов запросов.

1 голос
/ 13 февраля 2020

Во-первых, вся эта функция сама по себе бесполезна. Вам никогда не понадобится такая функция с PDO, когда вы можете отправить все значения напрямую в execute ().

Кроме того, это бесполезно, поскольку PDO::PARAM_NULL всегда применяется автоматически, PDO::PARAM_BOOL не работает с mysql, и большинство значений, которые вы отправляете в базу данных, являются строками, поэтому PDO::PARAM_INT также бесполезен .

Более того, в некоторых случаях это может быть даже вредно. Отправка int как строки - это нормально, но отправка строки как int может привести к катастрофе.

В любом случае, нет никакого способа связать значения в MySQL вручную, у вас есть возможность связать все значения одновременно.

Поскольку вы уже должны переписать какой-то код, я бы предложил вам код, который намного проще, но более мощный, чем ваш нынешний подход. Вот вспомогательная функция mysqli , которую я написал. Вы можете использовать его вместо своего класса PDO. Посмотрите раздел «Примеры» там, но просто для того, чтобы дать вам представление:

Предположим, прежде чем вам нужно было написать что-то вроде

$sql = "SELECT * FROM tmp_mysqli_helper_test WHERE id=?";
$db->prepare($sql);
$db->bind(1, $id);
$db->execute();
$row = $db->results();

С помощью этой вспомогательной функции вы можете получить почти такую ​​же, но более простую :

$sql = "SELECT * FROM tmp_mysqli_helper_test WHERE id=?";
$row = prepared_query($conn, $sql, [$id])->get_result()->fetch_assoc();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...