Генерация исключения при наличии транзакции

Вот мой сценарий:

try{

    $dbh_conn->beginTransaction();

    $user_id = $_POST['iuser_id'];
    $token   = hash('sha512', bin2hex(openssl_random_pseudo_bytes(16)).$user_id);

    $stmt = $dbh_conn->prepare("UPDATE resend_pass SET active = 0 WHERE user_id = ?");
    $stmt->execute(array($user_id));

    $stm = $dbh_conn
    ->prepare("INSERT INTO resend_pass(user_id, token, date_time)
                SELECT ?, ?, unix_timestamp()
                FROM dual
                WHERE NOT EXISTS( SELECT count(*) AS num_week,
                                    FROM resend_pass
                                   WHERE user_id   = ?  
                                     AND date_time > unix_timestamp() - 604800
                                  HAVING num_week > 11 ;");
    $stm->execute(array($user_id, $token, $user_id));

    // no row inserted (either there is lots of reuqests or duplicate token)
    if ( !$stm->rowCount() ) { throw new Exception('something is wrong'); }

    $dbh_conn->commit();

    /* sending an email contains reset_password_token here */

    $_SESSION["TopMSG"] = "<div class='msg_success'>has been sent</div>";
    header('location: ../login');
    exit;

} catch(Exception $e) {

    $dbh_conn->rollBack();

    $_SESSION["TopMSG"] = "<div class='msg_success'>$e</div>";
    header('location: ../login');
    exit;

}

Как видите, перед commit() стоит throw. Это нормально? На самом деле, когда я запускаю его, он не работает и выдает эту ошибку:

Неустранимая ошибка: Неперехваченное исключение «Исключение» в C:\xampp\htdocs\myweb\others\login.php:341 Трассировка стека: #0 C:\xampp\htdocs\myweb\application\other. php(35): login->resend_password_check() #1 C:\xampp\htdocs\myweb\index.php(150): require_once('C:\xampp\htdocs...') #2 {main} добавлено C:\xampp\htdocs\myweb\others\login.php в строке if ( !$stm->rowCount() ) { throw new Exception('something is wrong'); }

Как я могу это исправить?


person Martin AJ    schedule 13.07.2016    source источник
comment
Используете ли вы пространства имен? Кажется, ваш код не находит ваш класс Exception. BTW: можно генерировать исключения перед фиксацией. PS.: Я знаю, что это не контекст, но иметь выход в вашем коде нехорошо. Пусть поток запросов завершится изящно   -  person William Okano    schedule 14.07.2016


Ответы (1)


php Фатальная ошибка не поддается отлову.

Когда вы используете pdo, не пишите throw new Exception('что-то не так'); потому что PDO уже имеет это выражение PDOException

например:

try{
    $dbh_conn->beginTransaction();
    .......
    .......
    $stm->execute(array($user_id, $token, $user_id));
    ......
    $dbh_conn->commit();

}catch(PDOException $e) {
    print_r($e->getMessage());//Show excption message
    $dbh_conn->rollBack();
    $_SESSION["TopMSG"] = "<div class='msg_success'>$e</div>";

    //header('location: ../login');
    exit;
}
person Vanya Avchyan    schedule 13.07.2016
comment
Неправильно... мой запрос INSERT .. SELECT, и он не генерирует исключение, если строка не вставлена. Вот почему я написал, что throw. - person Martin AJ; 14.07.2016
comment
@Martin AJ PDO поймать эту ошибку INSERT .. SELECT.Write print_r($e-›getMessage()); в блок catch и вы убедитесь - person Vanya Avchyan; 14.07.2016
comment
сбой pdo не является фатальным для php. его можно поймать, как и все остальное. это становится фатальным только в том случае, если НИЧЕГО не перехватывает исключение (которое в любом случае не генерируется, если вы не включаете их явно). - person Marc B; 14.07.2016
comment
@Marc B В вопросе говорится, что Неустранимая ошибка: ... Не совсем так. Фатальные ошибки называются так, потому что они фатальны. Вы не можете исправить их. PHP не предоставляет обычных средств для обнаружения и восстановления после фатальных ошибок. - person Vanya Avchyan; 14.07.2016