Мне очень нравятся объявления возвращаемого типа в PHP, и я хочу использовать их в Symfony 3.
Все методы контроллера должны возвращать объект Response
, в этом нет проблем. Однако в репозиториях Doctrine Doctrine может возвращать объект Entity или null
.
Рассмотрим этот пример:
- Вы создали простую сущность
Post
. - Вы создали собственный метод
findByName
вPostRepository
:
PostRepository.php
public function findByName($name) : Post
{
$qb = $this->createQueryBuilder('p')
->where('p.name = :name')
->setParameter('name', $name);
$post = $qb->getQuery()->getOneOrNullResult();
return (null === $post) ? new Post() : $post;
}
Вы вызываете этот метод из контроллера, например:
DefaultController.php
/**
* @Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$repository = $em->getRepository('AppBundle:Post');
try {
$post = $repository->findByName('test');
} catch (\TypeError $e) {
$post = new Post();
}
return new Response(dump($post));
}
Я знаю, что попытка перехватить исключение не будет выполнена, потому что findByName()
всегда возвращает объект Post.
Мой вопрос: где мы должны обрабатывать исключение? Согласно этому ответу, лучше бросить исключение. Должны ли мы гарантировать, что метод репозитория вообще не выдает исключение, используя это:
$post = $qb->getQuery()->getOneOrNullResult();
return (null === $post) ? new Post() : $post;
или позволить PHP генерировать исключение TypeError и позволить контроллеру обработать его?
Doctrine создает исключения для методов getOneOrNullResult()
и getSingleResult()
, как описано здесь.
Если этот сценарий не имеет смысла, потому что лучше позволить вашему контроллеру обрабатывать исключение и возвращать страницу «не найдено», потому что сообщение не существует, как это:
return $this->createNotFoundException();
Сценарий №2
Post
существует в базе данных, и вызывается другой метод репозитория, getApprovedComments()
, комментарии не возвращаются, мы ожидаем ArrayCollection
, но получаем array
. Это вызовет исключение PHP TypeError
.
Я думаю, что код будет полон блоков try/catch. Можно ли обрабатывать такого рода исключения на более высоком уровне, чтобы в коде было меньше блоков try/catch?
На первый взгляд, это не лучшее решение, потому что код должен быть достаточно гибким, чтобы перехватывать каждое исключение TypeError
и предпринимать правильные действия по отображению страницы.
Response
, возникает исключениеLogicException
с этим сообщением: Контроллер должен вернуть ответ (нуль дан). Вы забыли добавить оператор возврата куда-нибудь в свой контроллер? - person ABC   schedule 22.02.2016@Template
возвращаетarray
. В этом случае этот конкретный метод действия контроллера будет иметьarray
в качестве объявления типа возвращаемого значения. - person ABC   schedule 23.02.2016