Mysql Вопрос про PDO и Close stmt

junior17

Новичок
Здравствуйте, просьба помочь разобраться с таким вопросом.

Есть такой код:

PHP:
$pdo=new PDO('mysql:host=localhost;dbname=test_db;charset=utf8','root', '',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false]);

try
{
 
    $pdo->beginTransaction();
 
    $result = $pdo->prepare('SELECT id FROM product WHERE id = ?');
    $result->execute(array(1));
    $row = $result->fetch();
 
    $result = $pdo->prepare('INSERT INTO brand SET title = ?');
    $result->execute(array('test'));
 
    $result = $pdo->prepare('INSERT INTO category SET title = ?');
    $result->execute(array('test'));
 
    $result = $pdo->prepare('INSERT INTO product SET price = ?');
    $result->execute(array('123'));
 
    $pdo->commit();
}
catch(PDOException $e)
{
    $pdo->rollBack();
}
2 Connect root@localhost as anonymous on test_db
2 Query START TRANSACTION
2 Prepare SELECT id FROM product WHERE id = ?
2 Execute SELECT id FROM product WHERE id = '1'
2 Prepare INSERT INTO brand SET title = ?
2 Close stmt
2 Execute INSERT INTO brand SET title = 'test'
2 Prepare INSERT INTO category SET title = ?
2 Close stmt
2 Execute INSERT INTO category SET title = 'test'
2 Prepare INSERT INTO product SET price = ?
2 Close stmt
2 Execute INSERT INTO product SET price = '123'
2 Query COMMIT
2 Close stmt
2 Quit

Как видим в логе подготовленный запрос закрывается до execute. Но если перед каждым новым подготовленным запросом очистить переменную

PHP:
$result = $pdo->prepare('SELECT id FROM product WHERE id = ?');
$result->execute(array(1));
$data = $result->fetchAll();
$result = null;
 
$result = $pdo->prepare('INSERT INTO brand SET title = ?');
$result->execute(array('test'));
$result = null;
 
$result = $pdo->prepare('INSERT INTO category SET title = ?');
$result->execute(array('test'));
$result = null;
 
$result = $pdo->prepare('INSERT INTO product SET price = ?');
$result->execute(array('123'));
2 Connect root@localhost as anonymous on test_db
2 Query START TRANSACTION
2 Prepare SELECT id FROM product WHERE id = ?
2 Execute SELECT id FROM product WHERE id = '1'
2 Close stmt
2 Prepare INSERT INTO brand SET title = ?
2 Execute INSERT INTO brand SET title = 'test'
2 Close stmt
2 Prepare INSERT INTO category SET title = ?
2 Execute INSERT INTO category SET title = 'test'
2 Close stmt
2 Prepare INSERT INTO product SET price = ?
2 Execute INSERT INTO product SET price = '123'
2 Query COMMIT
2 Close stmt
2 Quit

Close stmt срабатывает уже после execute. Просьба объяснить из-за чего такая разная последовательность? И как правильнее, перед каждым подготовленным запросом очищать переменную или в обоих вариантах нет никаких проблем? Спасибо.
 
Последнее редактирование:

флоппик

promotor fidei
Команда форума
Партнер клуба
Потому что у тебя в первом случае закрытие происходит тогда, когда неявно происходит сборка мусора в ненужных переменных, поскольку ты при каждом новом запросе используешь ту же переменную, не сохраняя обработанный стейтмент. Логически в твоих двух примерах нет разницы вообще, и когда очистился стейтмент не важно.
 

junior17

Новичок
Потому что у тебя в первом случае закрытие происходит тогда, когда неявно происходит сборка мусора в ненужных переменных, поскольку ты при каждом новом запросе используешь ту же переменную, не сохраняя обработанный стейтмент. Логически в твоих двух примерах нет разницы вообще, и когда очистился стейтмент не важно.
Эту часть не очень понял, можно про это чуть подробнее?
 

WMix

герр M:)ller
Партнер клуба
$result это stmt

$result = null; //Close stmt

$result->execute(...);
$result = $pdo->prepare(...) // сначало prepare, после замена $result на новый stmt, что ведет к "Close stmt" предыдущего
 
Сверху