Этот урок набрал набрал достаточно большое количество
комментариев и дальнейшее его комментирование отключено.
Если вы хотели убедиться в правильности выполнения ДЗ или у вас возник вопрос по уроку,
посмотрите ранее добавленные комментарии, кликнув по кнопке ниже. Скорее всего вы найдете там то, что искали.
Если это не помогло - задайте вопрос в чате в телеграме - https://t.me/php_zone
Спасибо за урок! Единственное, что заметил - это то, что если одновременно и ошибка при подключении к БД и несуществующий роут, то выдаст ошибку 404, а не 500. Так и должно быть?
Вроде на первый взгляд - несложная тема, но что-то в ступор вогнало((. Как-то не очень сразу понятно в конкретной ситуации, где оборачивать в try, где ловить исключение. Понятно одно - ловить исключение нет смысла раньше. чем оно может появиться, а пытаться обработать ситуацию на возможное исключение нужно заблаговременно до возможной ситуации. Сложность - в пространственном ориентировании - размещении try/catch сквозь слои классов и методов. Ну и осталась не менее интересная тема за кадром - обработка ошибок. Почему в курсе рассмотрены именно исключения, а ошибки обделены вниманием?
Почему тут try в самом начале кода, если автозагрузка классов, инициализация переменной route никак не влияет на возможное появление исключения - как то не найдена страница, или ошибка обращения к БД? Понятно, что такой большой захват кода в try не влияет в данном случае на логику, просто это вызывает дополнительные вопросы..
Понятное дело, что ошибки/исключения возникают в некой очередности, а не все одновременно. Затрудняюсь привести конкретный пример, где это было прямо очень важно/необходимо, но может же быть необходимым вывести несколько ошибок/исключений? Насколько правильно корректно - показывать только первую ошибку/исключение или если только ошибка не делает невозможным дальнейшее выполнение кода, - все, что возникли? Да, немного в кучу и ошибки и исключения, но думаю, что суть вопроса понятна).
Обрабатываемые исключения действительно могут броситься не во всем коде, обернутом в try. Можно блок try уменьшить. А можно добавить еще один catch с обработкой Throwable, на случай совсем уж непредвиденных ситуаций.
Если требуется вывести несколько ошибок, можно во-первых сформировать готовую строку с ошибками и в конце обернуть это в одно исключение. Во-вторых можно использовать интересный паттерн MultiException. Ознакомьтесь на досуге.
Добрый вечер. Прочитал про интерфейс Throwable и понял, что реализовать его в своем классе можно только путем расширения интерфейса (Throwable) своими методами. Затем в классе исключения использовать уже свой расширенный интерфейс.
У меня как-то так получилось (это все для примера, так как можно было обойтись и без своего нового метода):
index.php:
Достаточно было написать, что напрямую реализовать его нельзя) Но вы неплохо постарались)
А вот имена исключения и шаблона мне не нравятся. Для этого есть устоявшееся имя NotFound.
Спасибо вам за уроки. Умеете своими вопросами направить на путь более глубокого изучения отдельных областей.
Исключение и шаблон я уже исправил - это в предыдущем задании.
Пользовательские классы не могут реализовывать Throwable. Это было сделано для предсказуемости: только экземпляры Exception или Error могут быть брошены.
А в целом, что я понял: Можем ловить сначала Error, если не поймали, то ловим Throwable. Либо сразу Throwable.
? Даже если этот аттрибут явно не установлен, какие-то ошибки параметров соединения при попытке создания объекта в конструкторе класса Db приведут к выбрасыванию PDO исключения. Но, если возникает какая-то ошибка(например в синтаксисе) при попытке выполнить SQL запрос, то исключения будут сами выбрасываться только если установлен этот аттрибут. Почему в первом случае выбрасываются исключения и без этого аттрибута?
Может по этой причине?:
PDO::construct() выбрасывает исключение PDOException, если попытка подключения к запрашиваемой базе данных завершается с ошибкой.
Метод PDO::construct() будет всегда бросать исключение PDOException, если соединение оборвалось, независимо от установленного значения PDO::ATTR_ERRMODE. Непойманные исключения фатальны.
Для кого производится подобная обработка исключений, в контексте примера на картинке выше? С одной стороны - если для разработчика на время работы над проектом, зачем заменять более информативную штатную табличку исключения со стеком вызовов, кратким окружением - одной строкой сжатого текста об ошибке? Если для пользователей продукта - зачем выводить подробности ошибки?
Да, ошибка установления это всегда исключение. С синтаксисом по-хорошему тоже стоит так же поступать, но это почему-то оставили на усмотрение разработчиков приложений.
Вы правы, в реальных приложениях нужно давать разный контекст ошибок для разного окружения. Но у нас простейший учебный проект, в котором я не стал на эту тему заморачиваться и лишь показал пример обработки исключения. Дополнительно нарулить условия можете самостоятельно.
Пусть у нас есть 3 финкции: func1, func2 и func3. func1 вызывает внутри себя func2, а func2 вызывает func3.
В этом предложение есть отпечатка в слове "функции"
Проверил на практике, документация не врет)) Реализовать интерфейс напрямую нельзя.
Fatal error: Class MyProject\Exceptions\MyException cannot implement interface Throwable, extend Exception or Error instead in C:\OSPanel\domains\myproject.blog\src\MyProject\Exceptions\MyException.php on line 5
<?php
namespace MyProject\Exceptions;
class NotFoundException implements \Throwable
{
/** @var string */
protected $message;
/** @var int */
protected $code;
/** @var string */
protected $file;
/** @var int */
protected $line;
public function __construct(string $message = '', int $code = 0)
{
$this->message = $message;
$this->code = $code;
$this->file = __DIR__ . __FILE__;
$this->line = __LINE__;
}
public function getMessage(): string
{
return $this->message;
}
public function getCode(): int
{
return $this->code;
}
public function getFile(): string
{
return $this->file;
}
public function getLine(): int
{
return $this->line;
}
public function getTrace() : array
{
// Не знаю как реализовать
return [];
}
public function getTraceAsString(): string
{
// Не знаю как реализовать
return '';
}
public function getPrevious(): \Throwable
{
return \Throwable::getPrevious();
}
public function __toString(): string
{
return \Throwable::__toString();
}
}
1) в тексте та же ошибка, которую я ловлю
2) код ничем не отличается от предоставленного в уроке
3) ошибка дублируется по неизвестной мне причине (сначала PDOException, потом только созданное нами DbException)
Я прочитал текст ошибки, но что мне это даёт? Я же ловлю \PDOException и инициирую \DbException, почему выводится окно с сообщением о возникшем \PDOException? Не говоря уже об окне с \DbException
Так ведь и нужно, чтобы эта ошибка была! Не нужно только, чтобы возникали дополнительные окна с сообщениями об этой ошибке, а только текст "Хьюстон, у нас проблема! Ошибка при подключении к базе данных: (текст ошибки)". Вопрос в том, почему там ещё и окна, как на скриншоте, который я прикрепил в первом сообщении?
Разобрался. В моём php.ini директива xdebug.show_exception_trace имела значение 1, её необходимо выставить в 0. Теперь выводится только то, что я говорю выводить в случае пойманного исключения
Огромное спасибо за уроки! Суперские, современные, с учётом всех модных фишек (нэймспейсы, дебаггер, ловля ошибок и т.д.) - учите, как писать код правильно, надоело мне говнокодить, хочу творить красиво!
Нашел баг, на страницах с ошибкой не отображается имя пользователя. Пользователь может подумать, что его выкинуло с сайта и от этого ошибка, но авторизоваться повторно не сможет. В общем запутается.
что же дальше? будут Composer? и хочется делать и решать реальные задачки? вроде как писать блог? это возможно?
Да, всё это будет в скором времени.
Домашку сначала сделай)))
Классы PHP не могут напрямую реализовать интерфейс Throwable, . (Ссылка на документацию)
Верно!
Спасибо за урок! Единственное, что заметил - это то, что если одновременно и ошибка при подключении к БД и несуществующий роут, то выдаст ошибку 404, а не 500. Так и должно быть?
Зависит от того, какая ошибка возникнет первой.
Вроде на первый взгляд - несложная тема, но что-то в ступор вогнало((. Как-то не очень сразу понятно в конкретной ситуации, где оборачивать в try, где ловить исключение. Понятно одно - ловить исключение нет смысла раньше. чем оно может появиться, а пытаться обработать ситуацию на возможное исключение нужно заблаговременно до возможной ситуации. Сложность - в пространственном ориентировании - размещении try/catch сквозь слои классов и методов. Ну и осталась не менее интересная тема за кадром - обработка ошибок. Почему в курсе рассмотрены именно исключения, а ошибки обделены вниманием?
Есть и более конкретные вопросы:
Почему тут try в самом начале кода, если автозагрузка классов, инициализация переменной route никак не влияет на возможное появление исключения - как то не найдена страница, или ошибка обращения к БД? Понятно, что такой большой захват кода в try не влияет в данном случае на логику, просто это вызывает дополнительные вопросы..
Понятное дело, что ошибки/исключения возникают в некой очередности, а не все одновременно. Затрудняюсь привести конкретный пример, где это было прямо очень важно/необходимо, но может же быть необходимым вывести несколько ошибок/исключений? Насколько правильно корректно - показывать только первую ошибку/исключение или если только ошибка не делает невозможным дальнейшее выполнение кода, - все, что возникли? Да, немного в кучу и ошибки и исключения, но думаю, что суть вопроса понятна).
Спасибо за урок!
А что это за переменная $e, которую передаем в функцию исключения?
В какую функцию исключения? Не вижу тут функцию
Да, я не правильно выразился, это класс, но вопрос остался, мы не объявляли переменную $e, но пользуемся ей,можно узнать, что это за переменная?
Прочитайте официальную документацию по try-catch. Если не будет понятно, напишите в личку.
Добрый вечер. Прочитал про интерфейс Throwable и понял, что реализовать его в своем классе можно только путем расширения интерфейса (Throwable) своими методами. Затем в классе исключения использовать уже свой расширенный интерфейс.
У меня как-то так получилось (это все для примера, так как можно было обойтись и без своего нового метода):
index.php:
NotId.php:
NotIdException.php:
ArticleController.php:
Но такой способ использовать не рекомендуют. Это так или нет? И вообще такой способ где-то используется в практике?
Достаточно было написать, что напрямую реализовать его нельзя) Но вы неплохо постарались)
А вот имена исключения и шаблона мне не нравятся. Для этого есть устоявшееся имя NotFound.
Спасибо вам за уроки. Умеете своими вопросами направить на путь более глубокого изучения отдельных областей.
Исключение и шаблон я уже исправил - это в предыдущем задании.
Хорошо) Навык самостоятельно искать информацию - самый важный для программиста. Мы мастера спорта по гуглению)
Что-то пропустил, куда у нас делся
Из public function view(int $articleId) в ArticleController?
Ты чего? Это всё в ActiveRecordEntity, причем несколько уроков как.
ДЗ с подвохом)
А в целом, что я понял: Можем ловить сначала Error, если не поймали, то ловим Throwable. Либо сразу Throwable.
Да можно сразу Throwable
Когда НЕ НАЙДЕН??
В каких случаях необходимо устанавливать
? Даже если этот аттрибут явно не установлен, какие-то ошибки параметров соединения при попытке создания объекта в конструкторе класса Db приведут к выбрасыванию PDO исключения. Но, если возникает какая-то ошибка(например в синтаксисе) при попытке выполнить SQL запрос, то исключения будут сами выбрасываться только если установлен этот аттрибут. Почему в первом случае выбрасываются исключения и без этого аттрибута?
Может по этой причине?:
Для кого производится подобная обработка исключений, в контексте примера на картинке выше? С одной стороны - если для разработчика на время работы над проектом, зачем заменять более информативную штатную табличку исключения со стеком вызовов, кратким окружением - одной строкой сжатого текста об ошибке? Если для пользователей продукта - зачем выводить подробности ошибки?
Спасибо, исправил)
Да, ошибка установления это всегда исключение. С синтаксисом по-хорошему тоже стоит так же поступать, но это почему-то оставили на усмотрение разработчиков приложений.
Вы правы, в реальных приложениях нужно давать разный контекст ошибок для разного окружения. Но у нас простейший учебный проект, в котором я не стал на эту тему заморачиваться и лишь показал пример обработки исключения. Дополнительно нарулить условия можете самостоятельно.
ОК. Спасибо.
Пусть у нас есть 3 финкции: func1, func2 и func3. func1 вызывает внутри себя func2, а func2 вызывает func3.
В этом предложение есть отпечатка в слове "функции"
Большое спасибо, исправил
Интерфейс Throwable напрямую реализовать нельзя. В нём хранятся только подклассы Exception и Error.
Верно
Проверил на практике, документация не врет)) Реализовать интерфейс напрямую нельзя.
Fatal error: Class MyProject\Exceptions\MyException cannot implement interface Throwable, extend Exception or Error instead in C:\OSPanel\domains\myproject.blog\src\MyProject\Exceptions\MyException.php on line 5
Отлично
NotFoundException.php
Попытка запустить скрипт привела к
Класс MyProject\Exceptions\NotFoundException не может реализовывать интерфейс Throwable, вместо этого следует наследовать класс Exception или Error.
Спустя некоторое время понял что:
Всё верно
Добрый день!
Почему в моём случае отображаются ещё и окна с ошибками, а не только Хьюстон и строчка с текстом ошибки?
Конструктор класса Db:
src/MyProject/services/Db.php
src\MyProject\Exceptions\DbException.php
www\index.php
Текст ошибки пробовали читать?
1) в тексте та же ошибка, которую я ловлю
2) код ничем не отличается от предоставленного в уроке
3) ошибка дублируется по неизвестной мне причине (сначала PDOException, потом только созданное нами DbException)
Я прочитал текст ошибки, но что мне это даёт? Я же ловлю \PDOException и инициирую \DbException, почему выводится окно с сообщением о возникшем \PDOException? Не говоря уже об окне с \DbException
При чем тут класс? Текст ошибки читайте. Нет такой базы.
Так ведь и нужно, чтобы эта ошибка была! Не нужно только, чтобы возникали дополнительные окна с сообщениями об этой ошибке, а только текст "Хьюстон, у нас проблема! Ошибка при подключении к базе данных: (текст ошибки)". Вопрос в том, почему там ещё и окна, как на скриншоте, который я прикрепил в первом сообщении?
Ох ёлки) Прошу прощения за невнимательность.
Дебаггером смотрели, что может пойти не так?
Самый простой путь - подобавлять echo 1, echo 2 и т.д. по коду, и понять, в каком месте вылетает ошибка.
Разобрался. В моём php.ini директива xdebug.show_exception_trace имела значение 1, её необходимо выставить в 0. Теперь выводится только то, что я говорю выводить в случае пойманного исключения
Огромное спасибо за уроки! Суперские, современные, с учётом всех модных фишек (нэймспейсы, дебаггер, ловля ошибок и т.д.) - учите, как писать код правильно, надоело мне говнокодить, хочу творить красиво!
На здоровье!)
Пожалуйста, помогите!
Нашел баг, на страницах с ошибкой не отображается имя пользователя. Пользователь может подумать, что его выкинуло с сайта и от этого ошибка, но авторизоваться повторно не сможет. В общем запутается.
Как исправить?)
Сделать как и во вьюхе, чтобы объект юзера всегда был в исключения. Ну я в общем сделал уже)
Молодцом!
Поделитесь, пожалуйста, данным участком кода.
Спасибо!
Подсмотрел в документации, классы не могут реализовать Throwable только через интерфейс и от класса Exception
Верно
в коде в ArticlesController в методе add() ,видимо опечатка: добавлен
$article->delete();
Спасибо, поправил