PHP PDO 'SQLSTATE [HY093]: недопустимый номер параметра: параметр не был определен

Вот уже пару дней борюсь с этим ...

Сразу после подключения к БД -

    $this->sqladdimport = $this->db->prepare('INSERT INTO `importqueue`
                    (`user_id`, `service_id`, `format`, `comment`, `data`, `status`)
                VALUES (:user, :service, :format, ":commment", :file, :status)',
                 array(PDO::ATTR_EMULATE_PREPARES=>true));

Вызывается -

function addImportQueue($filename, $user, $format, $service_id, $comment, $status = IMPORT_NEW ){
    $fh = fopen($filename, 'r');
    if (!$fh) {
        return false;
    }

    $params = array(    ':user' => $user['user_id'],
                        ':format' => $format,
                        ':service' => $service_id,
                        ':comment' => $comment,
                        ':status' => $status) ;
    $this->sqladdimport->bindParam(':file', $fh, PDO::PARAM_LOB);
    foreach ($params as $key => &$val){
        $this->sqladdimport->bindParam($key,$val);
    }

    $this->sqladdimport->execute();
    $id = $this->db->lastInsertId();

    return $id;
}

Но я просто получаю

PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid parameter number: parameter was not defined'

в строке выполнения.

В случае необходимости таблица определяется следующим образом:

CREATE TABLE `importqueue` (
`import_id` INT(11) NOT NULL AUTO_INCREMENT,
`service_id` INT(11) NOT NULL DEFAULT '0',
`format` INT(11) NULL DEFAULT '0',
`user_id` INT(11) NULL DEFAULT '0',
`comment` TEXT NULL,
`date` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`data` MEDIUMBLOB NULL,
`status` INT(11) NULL DEFAULT NULL,
INDEX `Index 1` (`import_id`)
)
COMMENT='Import queue/archive'
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;

Я новичок в PDO, и особенно в BLOB, поэтому я, вероятно, делаю что-то действительно явно глупое, но в настоящее время это ускользает от меня!

Спасибо!

Редактировать: Я отмечаю ссылки на кавычки вокруг: comment в файле prepare - это артефакт моей отладки, и я удалил их снова без изменений.

Также упростили функцию до

    $fh = fopen($filename, 'r');
    $this->sqladdimport->bindValue(':file', $fh, PDO::PARAM_LOB);
    $this->sqladdimport->bindValue(':user', $user['user_id']);
    $this->sqladdimport->bindValue(':format', $format);
    $this->sqladdimport->bindValue(':service', $service_id);
    $this->sqladdimport->bindValue(':comment', $comment);
    $this->sqladdimport->bindValue(':status', $status);
    $this->sqladdimport->execute();

и я все еще получаю ту же ошибку (используя либо bindParam, либо bindValue)

Не заключайте заполнители в кавычки, PDO / mysqli будет думать, что это просто строки, а не заполнители.

aynber 13.09.2018 19:55

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

user2158583 13.09.2018 20:00

Почему вы определяете массив параметров связывания и после этого объединяете их в цикл? Почему вы не связываете их напрямую?

Jens 13.09.2018 20:06

Просто интересно, почему у вас ": comment" только в двойных кавычках. Я считаю это виновником

Rinsad Ahmed 13.09.2018 20:06

Йенс - Следствие копирования других примеров. Изначально у меня было все как array () внутри выполнения, но были те же ошибки. прочитал, что мне нужен PDO :: PARAM_LOB в параметре файла, поэтому разделите его.

user2158583 13.09.2018 20:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
6
6 386
3

Ответы 3

см. Ключевые слова и зарезервированные слова ...

вы можете захотеть переименовать столбцы comment, date, format и status.

Invalid parameter number исходит из ":comment", который не заменяется, поэтому количество столбцов не соответствует количеству параметров, за вычетом одного. чтобы подготовленный оператор содержал правильное количество параметров, он должен быть :comment.

Это ключевые слова, но они не зарезервированы. OP имеет их в обратных кавычках, поэтому использование в порядке.

aynber 13.09.2018 20:12

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

Martin Zeitler 13.09.2018 20:21

Спасибо, я могу настроить имена полей в продакшене (еще не поздно сделать это), но сначала пытаюсь наладить функциональность ..

user2158583 13.09.2018 20:22

У вас есть только заполнитель «: комментарий» в двойных кавычках. Следовательно, он будет рассматриваться как строка

Также, если вы пытаетесь сохранить двоичный файл, используйте

$fh = fopen($filename, 'rb');

вместо того

$fh = fopen($filename, 'r');

Кроме того, попробуйте определить тип данных для всех столбцов, потому что метод bindValue имеет третий столбец, который по умолчанию равен PDO :: PARAM_STR. Но у вас тоже есть числовые столбцы

$fh = fopen($filename, 'rb');
$this->sqladdimport->bindValue(':file', $fh, PDO::PARAM_LOB);
$this->sqladdimport->bindValue(':user', $user['user_id'],PDO::PARAM_INT);
$this->sqladdimport->bindValue(':format', $format,PDO::PARAM_INT);
$this->sqladdimport->bindValue(':service', $service_id,PDO::PARAM_INT);
$this->sqladdimport->bindValue(':comment', $comment,PDO::PARAM_STR);
$this->sqladdimport->bindValue(':status', $status,PDO::PARAM_INT);
$this->sqladdimport->execute();

Я изменил это, и моя проблема не решена :(

user2158583 13.09.2018 20:21

@ user2158583 ваш файл - двоичный файл или текстовый файл?

Rinsad Ahmed 13.09.2018 20:22

Ах. Это текст, но с различными непечатаемыми символами. Я должен относиться к нему как к двоичному, так как я не хочу ничего менять. Изменен на 'rb', но ошибка все равно появляется.

user2158583 13.09.2018 20:32

Вы тоже исправили заполнитель ": comment"?

Rinsad Ahmed 13.09.2018 20:33

Я сделал. $this->sqladdimport = $this->db->prepare('INSERT INTO importqueue` (user_id, service_id, format, comment, data, status) VALUES (: user,: service,: format,: commment,: file,: status) ', array (PDO :: ATTR_EMULATE_PREPARES => true)); `

user2158583 13.09.2018 20:36

Нашел ....

Я скопировал код в тестовый сценарий, который мне было легче изменить. Начал с одного поля (которое работало) и постепенно добавлял остальные одно за другим.

Проблема оказалась в простой опечатке в команде подготовки ... Это относится к: комментарий. Привязка имела в виду: комментарий. Я никогда не замечал лишнего "м" ..

Спасибо всем за все предложения. Это был познавательный опыт!

Другие вопросы по теме