Обработка ошибок MySQL

Zavus

Новичок
Имеется , например , такое:
Код:
    $db_host = "localhost";
    $db_username = "root";
    $db_password = "12345678";
    $db_name = "data_base";
    $link= mysqli_connect($db_host, $db_username, $db_password, $db_name) ;
    if (!$link) {
       echo 'Что-то пошло не так';   
       exit();
    }
  
       $login = 'Vasya';
       $stmt = mysqli_prepare($link, 'SELET id FROM users WHERE login = ? LIMIT 1');
       mysqli_stmt_bind_param($stmt, "s", $login );
       mysqli_stmt_execute($stmt);
       mysqli_stmt_store_result($stmt);
      
       if (mysqli_stmt_num_rows($stmt) >0){
           mysqli_stmt_bind_result($stmt, $user_id);
           echo 'ID Васи: '.$user_id.'</br>';
       }
       else {
           echo 'Не найден ID по Васе </br>';
       }
      
       mysqli_stmt_close($stmt);
Что бы хотелось понять, так это:

1) что может пойти не так на каждом из этапов запроса (у меня мало практики , полезно будет узнать "прожженные" мнения).

2) какие моменты обязательно надо обрабатывать, а где беспокоиться не о чем

И если не трудно, пару простейших примеров обработки ошибок запросов без ООП (пока не шарю).
 

WMix

герр M:)ller
Партнер клуба
Я не понимаю, что ты хочешь, какая такая "вася"?, допиши пример до конца.
 

WMix

герр M:)ller
Партнер клуба
Задай конкретно вопрос, какая из строк тебе непонятна. На этом этапе скрипт непотребный. Вылететь с сообщением "что-то пошло не так" это не обработка ошибок.
 

Фанат

oncle terrible
Команда форума
Несмотря на то что посылки неправильные, это очень характерный и очень хороший вопрос.
Сразу видно думающего человека, что на это форуме редкость.
Тем важнее сразу правильно расставить точки над ё.
что может пойти не так на каждом из этапов запроса
Всё.
Нет ни одного человека, который наизусть знает все те тысячи ошибок, которые тебе может выдать БД, драйвер, файловая система, пхп, что угодно.
Но самое интересное, что знать наперед это и не нужно.
какие моменты обязательно надо обрабатывать,
Никакие.
А точнее, только те, которые ты сам хочешь обработать.
Все остальные никак обрабатывать не нужно.

Главное, что надо понять - это разницу между информированием об ошибке и ее обработкой. Это абсолютно разные вещи, причем новички поголовно не понимают этой разницы.
Написать "Что-то пошло не так" - это не обработка. Это совершенно бессмысленные телодвижения, которые могут прнести только вред. Такой обработки быть вообще не должно.

Поэтому в общем случае на месте ошибки никак вообще обрабатывать не надо. Надо только сказать mysqli, чтобы оно кидало ошибки самостоятельно. Это делается командой
PHP:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
Все. Больше ничего делать не нужно. То есть твой код становится таким:
PHP:
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $link= mysqli_connect($db_host, $db_username, $db_password, $db_name) ;
 
    $login = 'Vasya';
    $stmt = mysqli_prepare($link, 'SELET id FROM users WHERE login = ? LIMIT 1');
    mysqli_stmt_bind_param($stmt, "s", $login );
    mysqli_stmt_bind_result($stmt, $user_id);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_store_result($stmt);
    mysqli_stmt_fetch();

    if ($user_id) {
        echo 'ID Васи: '.$user_id.'</br>';
    } else {
        echo 'Не найден ID по Васе </br>';
    }
Теперь в случае ошибки mysqli тебя о ней проинформирует автоматически. дальше она будет обработана так же, как все остальные ошибки на сайте.

Обрабатывать же конктено ошибки mysql приходится очень редко, и пока тебе это не нужно - только запутает.
 
Последнее редактирование:

Zavus

Новичок
Тем важнее сразу правильно расставить точки над ё.
Спасибо за такое подробное объяснение, наконец-то картина с ошибками значительно прояснилась... Только одна вещь осталась за кадром. В соседней теме https://phpclub.ru/talk/threads/Суть-обработки-ошибок.83804/#post-756231 Вы ответили, что любую ошибку надо воспринимать, как фатальную.

Допустим, есть страница , где только это:

Код:
 mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $link= mysqli_connect($db_host, $db_username, $db_password, $db_name) ;
 
    $login = 'Vasya';
    $stmt = mysqli_prepare($link, 'SELET id FROM users WHERE login = ? LIMIT 1');
    mysqli_stmt_bind_param($stmt, "s", $login );
    mysqli_stmt_bind_result($stmt, $user_id);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_store_result($stmt);
    mysqli_stmt_fetch();

    if ($user_id) {
        echo 'ID Васи: '.$user_id.'</br>';
    } else {
        echo 'Не найден ID по Васе </br>';
    }
Как на этом примере можно по-человечески реализовать обработчик, который , если что-то не так, будет показывать что-нибудь вроде "Извините, страница временно недоступна" ?
есть ли какие-нибудь типичные способы? )
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@Zavus, выбросить определенный тип exception, словить его в обработчике и уже от типа отплясав - показать то, что тебе надо.

Только у тебя $user_id нигде не определяется.
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
@Zavus
Только у тебя $user_id нигде не определяется.
Во-первых, определена, а во-вторых, как выбросить эксепшен, я ему уже показал :)
А в третьих, тип эксепшена в данном случае нас не волнует, поскольку показать ему надо "Извините, страница временно недоступна".
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@Фанат, я бинд резалт проглядел)

Тип волнует, почему нет
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@Фанат, неа, у тебя может быть разные "страницы недоступны", а внешний вид их может зависеть от типа. Имхо.
 

Фанат

oncle terrible
Команда форума
есть ли какие-нибудь типичные способы? )
Ну вот например, для PHP7+
PHP:
set_exception_handler('myExceptionHandler');
function myExceptionHandler($e)
{
    error_log($e);
    header('HTTP/1.1 503 Internal Server Error', TRUE, 503);
    echo "Извините, страница временно недоступна";
    exit;
}
 

Фанат

oncle terrible
Команда форума
@Фанат, неа, у тебя может быть разные "страницы недоступны", а внешний вид их может зависеть от типа. Имхо.
Ну в теории-то все может быть, но мы сейчас гворим о базовой обработке ошибок для человека, который пхп второй день видит.
Поэтому желательно показать ему самый базовый вариант и не растекаться мыслью по древу.
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума

Вурдалак

Продвинутый новичок
Это совершенно законный способ который используется повсеместно
Способ отображения ошибки зависит от контекста, контекст задаётся точкой входа, эту точку входа можно проконтролировать в одном месте, т.е. никакого «глобального» обработчика не требуется. Зачем использовать глобальный обработчик? Каким образом этот глобальный обработчик понимает контекст? Это из разряда «на всякий случай»?
 

fixxxer

К.О.
Партнер клуба
@Фанат, set_exception_handler() — это хак. Ты в CLI тоже показываешь HTML-страницу, что что-то там недоступно?
Кусок из Laravel-а:

PHP:
class HandleExceptions
{
...
   public function bootstrap(Application $app)
    {
        $this->app = $app;

        error_reporting(-1);

        set_error_handler([$this, 'handleError']);

        set_exception_handler([$this, 'handleException']);

        register_shutdown_function([$this, 'handleShutdown']);

        if (! $app->environment('testing')) {
            ini_set('display_errors', 'Off');
        }
    }
...
    public function handleException($e)
    {
        if (! $e instanceof Exception) {
            $e = new FatalThrowableError($e);
        }

        $this->getExceptionHandler()->report($e);

        if ($this->app->runningInConsole()) {
            $this->renderForConsole($e);
        } else {
            $this->renderHttpResponse($e);
        }
    }
:)

Я, правда, совершенно не понимаю, нафига это делать. Ладно какой-нибудь дефолтный bugsnag/sentry адаптер с подключением по принципу "сунул в композер и все".
Но чем не устраивает что-то совершенно банальное вида
PHP:
try {
    $this->run();
} catch (\Exception $e) {
    $this->handleException($e);
}
я не понимаю.
 

Вурдалак

Продвинутый новичок
законный способ который используется повсеместно
Кусок из Laravel-а:
Ребят, мне вообще пофиг где это используется, это аргумент из принципа «миллионы мух не могут ошибаться». Есть конкретные претензии, давайте не будем ссылаться на «авторитетов» для ответа.
 

fixxxer

К.О.
Партнер клуба
Ребят, мне вообще пофиг где это используется, это аргумент из принципа «миллионы мух не могут ошибаться». Есть конкретные претензии, давайте не будем ссылаться на «авторитетов» для ответа.
Ну я его ващет поржать скопипастил. ;)
 
Сверху