Дублирование данных при insert, где ошибка?

Здравствуйте!
Пытаюсь написать класс для работы с Mysql.
Когда записываю что-то в базу данных они дублируются и получается 2 записи вместо одной.

Класс простой
class DatabaseMysql
{
    
    private $pdo;
    private $dbc;

    public function __construct()
    {
        $this->dbc = require('./core/config/DbConfig.php');
        $this->pdo = new \PDO(
            'mysql:host=' . $this->dbc['db_host'] . ';dbname=' . $this->dbc['db_name'],
            $this->dbc['db_user'],
            $this->dbc['db_pass']
        );
    }
    public function insert(string $query, array $params)
    {

        $sth = $this->pdo->prepare($query);
        $res = $sth->execute($params);

        if (false === $res) {
            return null;
        }

        return $this->pdo->lastInsertId();
    }

}


Пытаюсь вставить данные
$db = new DatabaseMysql;

$res = $db->insert('INSERT INTO test_table (`name`, `age`) VALUES (?,?)', ['Ivan',43]);


В результате в базе 2 одинаковые строки.
Подскажите где я ошибаюсь?
  • Вопрос задан
  • 609 просмотров
Решения вопроса 1
FanatPHP
@FanatPHP
Чебуратор тега РНР
про проблему тебе все уже рассказали, все изменения в БД должны быть только методом POST.

Но поскольку вопрос изначально про класс, качестве шефской помощи перепишем его на более осмысленный, учитывая что

- доступ к инстансу ПДО должен быть не только изнутри
- а вот конфиг держать в переменной класса нужно как рыбке зонтик
- кодировку при соеднинеии с базой надо задавать, чтобы потом не плодить на тостере очередной пост, "у меня в базе вопросики записались"
- причем сразу правильную
- самое главное - вежливо попросить РНР сообщать обо всех ошибках в запросах
- ну и заодно установить разные удобные опции
- пути всегда должны быть абсолютными
- сначала надо написать универсальный метод для выполнения запросов, а потом уже использовать его во всех остальных методах
- ненужный код не нужен

class DatabaseMysql
{
    public $pdo;

    public function __construct()
    {
        $options = [
            \PDO::ATTR_ERRMODE            => \PDO::ERRMODE_EXCEPTION,
            \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
            \PDO::ATTR_EMULATE_PREPARES   => false,
        ];
        $dbc = require(__DIR__.'/core/config/DbConfig.php');
        $this->pdo = new \PDO(
            "mysql:host={$dbc['db_host']};dbname={$dbc['db_name']};charset=utf8mb4",
            $dbc['db_user'],
            $dbc['db_pass'],
            $options,
        );
    }
    public function query(string $query, array $params = [])
    {
        $sth = $this->pdo->prepare($query);
        $sth->execute($params);
        return $sth;
    }

    public function insert(string $query, array $params)
    {
        $this->query($query, $params);
        return $this->pdo->lastInsertId();
    }
}


Хотя если честно, то я большого смысла в этом классе не вижу.
Меня бы устроило простое расширение класса PDO типа такого
class MyPDO extends PDO
{
    public function run($sql, $bind = NULL)
    {
        $stmt = $this->prepare($sql);
        $stmt->execute($bind);
        return $stmt;
    }
}

Да, вставка будет выполняться за две строчки, а не одну,
$pdo->insert('INSERT INTO test_table (`name`, `age`) VALUES (?,?)', ['Ivan',43]);
$id = $pdo->lastInsertId();
но я не уверен что стоит городить целый класс из-за одной строчки.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@galaxy
В этом коде на первый взгляд все ок. Ошибка где-то еще, вероятно. Попробуйте логировать пошагово.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы