Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Doctrine orm 条令存储库方法的Symfony3和PHP7返回类型偏差_Doctrine Orm_Symfony_Php 7 - Fatal编程技术网

Doctrine orm 条令存储库方法的Symfony3和PHP7返回类型偏差

Doctrine orm 条令存储库方法的Symfony3和PHP7返回类型偏差,doctrine-orm,symfony,php-7,Doctrine Orm,Symfony,Php 7,我非常喜欢PHP的返回类型声明,我想在Symfony 3上使用它 所有控制器方法都应该返回响应对象,没有问题。但在条令存储库中,条令可能返回实体对象,或null 考虑这个例子: 您已经创建了一个简单的Post实体 您已经在PostRepository中创建了一个自定义findByName方法: PostRepository.php public function findByName($name) : Post { $qb = $this->createQueryBuilder

我非常喜欢PHP的返回类型声明,我想在Symfony 3上使用它

所有控制器方法都应该返回
响应
对象,没有问题。但在条令存储库中,条令可能返回实体对象,或
null

考虑这个例子:
  • 您已经创建了一个简单的
    Post
    实体
  • 您已经在
    PostRepository
    中创建了一个自定义
    findByName
    方法:
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;
}
/**
 * @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));
}
您可以从控制器调用此方法,如下所示:

return $this->createNotFoundException();
DefaultController.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;
}
/**
 * @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异常并让控制器处理它

条令,为所述的
getOneOrNullResult()
getSingleResult()
方法抛出异常

如果此场景没有意义,因为最好让您的控制器处理异常并返回“未找到”页面,因为post不存在如下情况:

return $this->createNotFoundException();
情景2
Post
存在于数据库中,另一个存储库方法被调用,
getApprovedComments()
,不会返回任何注释,我们希望得到一个
ArrayCollection
,但我们得到一个
数组。这将引发PHP的
TypeError
异常

我认为代码将充满try/catch块。在更高级别上处理此类异常以减少代码中的try/catch块可以吗


再想一想,这不是最好的解决方案,因为代码应该足够灵活,能够捕捉到每一个
类型错误
异常,并对如何呈现页面采取适当的操作。

无论您做什么,您绝对不应该捕捉类型错误或任何其他错误。如果发生错误,则意味着编程错误,必须通过避免引发错误的条件来解决。这就是错误与异常区别的目的。您应该只捕获顶级异常处理程序中的错误,或者如果您处于某个非常特殊的情况下。@NikiC谢谢,但这意味着用户将在站点前端看到异常,因为数据库查询未返回预期结果?若错误被隐藏,用户将只看到一个错误页面?总之,我需要确保无论发生什么情况,方法总是返回正确的类型。请提供任何官方来源来支持您的声明,好吗?您应该知道,Symfony控制器操作方法不需要返回响应对象,而且通常不需要。这只是我的观点,但我认为您可能过于复杂了。@Cerad根据“控制器是您创建的可调用PHP,它从HTTP请求获取信息,创建并返回HTTP响应(作为Symfony响应对象)。”。如果控制器操作方法没有返回
响应
对象,则会抛出一个
逻辑异常
异常,并显示以下消息:“控制器必须返回响应(给定null)。您是否忘记在控制器的某个位置添加返回语句?”看起来文档需要进行一些调整。请求处理程序检查调用控制器操作的结果。如果它不是响应,那么它将结果发送给侦听器,侦听器反过来可以生成响应。例如,sensio@template指令就是这样工作的:。如您所见,控制器返回一个数组。顺便说一句,这是我通常建议在尝试过多调整之前构建一些应用程序的一个原因。不管你做什么,你绝对不应该捕捉到类型错误或任何其他错误。如果发生错误,则意味着编程错误,必须通过避免引发错误的条件来解决。这就是错误与异常区别的目的。您应该只捕获顶级异常处理程序中的错误,或者如果您处于某个非常特殊的情况下。@NikiC谢谢,但这意味着用户将在站点前端看到异常,因为数据库查询未返回预期结果?若错误被隐藏,用户将只看到一个错误页面?总之,我需要确保无论发生什么情况,方法总是返回正确的类型。请提供任何官方来源来支持您的声明,好吗?您应该知道,Symfony控制器操作方法不需要返回响应对象,而且通常不需要。这只是我的观点,但我认为您可能过于复杂了。@Cerad根据“控制器是您创建的可调用PHP,它从HTTP请求获取信息,创建并返回HTTP响应(作为Symfony响应对象)。”。如果控制器操作方法没有返回
响应
对象,则会抛出一个
逻辑异常
异常,并显示以下消息:“控制器必须返回响应(给定null)。您是否忘记在控制器的某个位置添加返回语句?”看起来文档需要进行一些调整。请求处理程序检查调用控制器操作的结果。如果它不是响应,那么它将结果发送给侦听器,侦听器反过来可以生成响应。例如,sensio@template指令就是这样工作的:。如您所见,控制器返回一个数组。顺便说一句,这是我通常建议在尝试过多调整之前构建一些应用程序的原因之一。