We ask MySQL to prepare the statement, save the allocated resources internally, execute the statement immediately and then discard the PDOStatement object that was received from prepare(). When the object is discarded, there is still one status message pending on the connection, but mysqlnd silently fetches it and discards it.
Fourth is to never assign the result object to any PHP variable.
объект, на который нет ссылок, уничтожается
2024-06-27T13:26:48.661692Z 8 Connect dev@localhost on test_db using TCP/IP
2024-06-27T13:26:48.662365Z 8 Query CREATE TABLE IF NOT EXISTS `test` (`id` INT NOT NULL, `name` VARCHAR(45) NULL, PRIMARY KEY (`id`));
2024-06-27T13:26:48.671968Z 8 Query DELETE FROM `test`;
2024-06-27T13:26:48.674903Z 8 Query INSERT INTO `test` VALUES(1, 'A'), (2, 'B')
2024-06-27T13:26:48.676598Z 8 Query CREATE TABLE IF NOT EXISTS `test_a` (`id` INT NOT NULL, `name` VARCHAR(45) NULL, PRIMARY KEY (`id`));
2024-06-27T13:26:48.679305Z 8 Query DELETE FROM `test_a`;
2024-06-27T13:26:48.681422Z 8 Query INSERT INTO `test_a` VALUES(1, 'A'), (2, 'B')
2024-06-27T13:26:48.683191Z 8 Query CREATE TABLE IF NOT EXISTS `test_b` (`id` INT NOT NULL, `name` VARCHAR(45) NULL, PRIMARY KEY (`id`));
2024-06-27T13:26:48.684910Z 8 Query DELETE FROM `test_b`;
2024-06-27T13:26:48.686423Z 8 Query INSERT INTO `test_b` VALUES(1, 'A'), (2, 'B')
2024-06-27T13:26:48.687933Z 8 Quit
2024-06-27T13:27:22.843952Z 9 Connect root@localhost on using SSL/TLS
2024-06-27T13:27:22.844173Z 9 Query set autocommit=1
2024-06-27T13:27:22.844346Z 9 Query SELECT current_user()
2024-06-27T13:27:22.844551Z 9 Query SET CHARACTER SET utf8
2024-06-27T13:27:22.844694Z 9 Query SET NAMES utf8
2024-06-27T13:27:22.844829Z 9 Query SELECT CONNECTION_ID()
2024-06-27T13:27:22.845003Z 9 Query show character set where charset = 'utf8mb4'
2024-06-27T13:27:22.848080Z 9 Query SET NAMES 'utf8mb4'
2024-06-27T13:27:22.848289Z 9 Query SHOW SESSION STATUS LIKE 'Ssl_cipher'
2024-06-27T13:27:22.850108Z 9 Query USE `catquest_prod`
2024-06-27T13:27:22.850256Z 9 Query set autocommit=1
2024-06-27T13:27:22.850925Z 9 Query DROP TABLE `catquest_prod`.`test`, `catquest_prod`.`test_a`, `catquest_prod`.`test_b`
2024-06-27T13:28:42.488351Z 10 Connect dev@localhost on test_db using TCP/IP
2024-06-27T13:28:42.488678Z 10 Query CREATE TABLE IF NOT EXISTS `test` (`id` INT NOT NULL, `name` VARCHAR(45) NULL, PRIMARY KEY (`id`));
2024-06-27T13:28:42.504759Z 10 Query DELETE FROM `test`;
2024-06-27T13:28:42.505702Z 10 Query INSERT INTO `test` VALUES(1, 'A'), (2, 'B')
2024-06-27T13:28:42.507564Z 10 Quit
проверять свои выкладки
Чувак забронзовел
$conn->prepare($sql)->execute($params1)->execute($params2);
чтобы ему разжевали, как работает сборка мусора при удалении переменной
(int) $_GET['id']
. Сам всегда так делал и ни разу не получил проблем. что чтобы получить ошибку, результат надо получить
ваши инсерты работают потому что в режиме эмуляции
потому что вы не запросили результаты своих запросов, и они остались ждать на сервере
которое пытаетесь формулировать через какой-то детский лепет про "параллельное выполнение"
по завершении работы функции всем её переменным делается unset
при этом куда проще выполнять запросы по одному: тогда не нужно проверять результат каждого вручную
С чего это вы взяли, что мы ровесники? Вы вообще кто? Контрибьютоор в PHP? Как давно вы тут?
Не надо судить людей по себе :) И кстати, где нерегулярность? Я не пропадал неделями, вроде.
И опять вы не правы. Этого нет. Точнее, есть, но только в PDO::exec(), для подготовленных запросов этого точно нет.
Идеальный патч, на мой взгляд, хранил бы в драйвере пул всех открытых соединений, и закрывал все старые соединения при попытке открыть новое, даже если программист не закрыл курсор и не получил результаты. Это позволило бы не беспокоиться о получении ответа, когда он не нужен, и не ловить SQL state error 2014.
Но это не самый простой патч, и потенциально он может привести к росту потребления памяти и не только. Поэтому вряд ли его когда-то реализуют.
Есть вероятность, что там доступен результат только последнего подзапроса. Но это опять же не точно, нужна проверка.
Вообще вы оба с Камилем пропустили очевиднейшую вещь. Если бы вы её нашли, этот тред можно было бы закрыть в первый же день.
А именно, это не особенность мультизапросов в PDO. Это так со всеми prepared запросами.
Нельзя открывать новый, не закрыв старый, сделав unset() переменной или прочитав его результаты, и всё тут.
Можно было сразу так и ответить - но вы не в ту степь все ушли. Ну и я конечно дурак, не проверил кейс с одиночными подготовленными запросами без очистки переменных.