Чтобы использовать методы и член объекта, вам сначала нужно создать этот объект. Если вы его не создали (переменная, которая должна содержать объект, не инициализируется), но вы пытаетесь использовать его методы или переменные, вы получите эту ошибку.
Иногда вы можете просто забыть инициализировать .
Отредактировано: new не может вернуть значение null, но исключение огня при ошибке. Давно это было на некоторых языках, но не больше. Спасибо @John Saunders за указание на это.
Я бы не готовил & amp; выполнять транзакционные заявления. Я использовал бы PDO :: beginTransaction () , PDO :: commit () и PDO :: rollback () .
PDO :: prepare () и PDO :: execute () возвращают FALSE, если есть ошибка, иначе они генерируют исключение PDOException, если вы setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION) .
В вашем обработчике исключений вы должны проверить PDO :: errorInfo () и сообщить о характере ошибки. Лучше всего регистрировать необработанную информацию об ошибке, но дать пользователю более дружественное сообщение.
Не эхо-буквенное сообщение об ошибке в пользовательском интерфейсе - это может дать пользователю неуместные знания о вашем SQL-запросе и схема.
Некоторые общие замечания: Не используйте bindParam()
, если вы не используете процедуру, которая изменяет значение параметра. Поэтому use bindValue()
. bindParam () принимает значение аргумента как ссылочную переменную. Это означает, что вы не можете сделать $stmt->bindParam(':num', 1, PDO::PARAM_INT);
- это вызывает ошибку. Кроме того, PDO имеет свои собственные функции для управления транзакциями, вам не нужно выполнять запросы вручную.
Я немного переписал ваш код, чтобы пролить свет на то, как можно использовать PDO:
if($_POST['groupID'] && is_numeric($_POST['groupID']))
{
// List the SQL strings that you want to use
$sql['privileges'] = "DELETE FROM users_priveleges WHERE GroupID=:groupID";
$sql['groups'] = "DELETE FROM groups WHERE GroupID=:groupID"; // You don't need LIMIT 1, GroupID should be unique (primary) so it's controlled by the DB
$sql['users'] = "DELETE FROM users WHERE Group=:groupID";
// Start the transaction. PDO turns autocommit mode off depending on the driver, you don't need to implicitly say you want it off
$pdo->beginTransaction();
try
{
// Prepare the statements
foreach($sql as $stmt_name => &$sql_command)
{
$stmt[$stmt_name] = $pdo->prepare($sql_command);
}
// Delete the privileges
$stmt['privileges']->bindValue(':groupID', $_POST['groupID'], PDO::PARAM_INT);
$stmt['privileges']->execute();
// Delete the group
$stmt['groups']->bindValue(":groupID", $_POST['groupID'], PDO::PARAM_INT);
$stmt['groups']->execute();
// Delete the user
$stmt['users']->bindParam(":groupID", $_POST['groupID'], PDO::PARAM_INT);
$stmt['users']->execute();
$pdo->commit();
}
catch(PDOException $e)
{
$pdo->rollBack();
// Report errors
}
}
Задание PDO execute()
возвращает TRUE при успешном завершении и FALSE при сбое, поэтому вы можете проверить возвращаемое значение предыдущего execute()
в вашем операторе if.
$pdo_result = $dbs->execute();
if ($pdo_result) {
// handle success
} else {
// handle failure
// you can get error info with $dbs->errorInfo();
}
Это говорит о том, что @ Билл Кервин правильно указывает (в своем ответе, что я полностью выдвигаю, потому что это точно правильно), было бы предпочтительнее использовать PDO::beginTransaction()
, PDO::commit()
и PDO::rollback()
.