duanran6441 2013-11-18 10:03
浏览 35
已采纳

Symfony2和Doctrine有空关系

I just started learning Symfony2 (and I do not have much php experience), so my question may seem funny for someone. I'm now following Databases and Doctrine section of The Book, and my question concerns Fetching Related Objects example (I use the same code as in documentation, so I won't paste all of it here).

There is a code that fetches associated objects in this example:

public function showAction($id)
{
    $product = $this->getDoctrine()->getRepository('AcmeStoreBundle:Product')->find($id);
    $categoryName = $product->getCategory()->getName();

    return array('product' => $product, 'category' => $categoryName);
}

When I run this controller on a Product object that has category reference set in DB everything works fine. Unfortunately, when category is null it throws "FatalErrorException: Error: Call to a member function getName() on a non-object".

I understand that this is because there is no Category object and so no Category name, but my question is what is the best way to handle such situations? I want $categoryName to return null or empty string to use in my template, just like any other not set property of Product object, but since it comes from associated object I'm stuck on this problem

  • 写回答

2条回答 默认 最新

  • dongxi9326 2013-11-18 10:38
    关注

    You might be expecting: When $product->getCategory() is called if $product has no Category, it returns empty Category.

    If so, let's code so.

    Constructor should be:

    class Product
    {
        /**
         * @var Category $category
         */
        private $category; //clearly mentions that Product has ONE category
    
        public function __construct()
        {
            $this->category = new Category();
            //initialize this so $this->category is no longer a non-object
        }
    }
    

    EDIT:

    You're still get same error because that doctrine just synchronizes records into class-map like

    $product = new Product();
    $product->setName();
    ...
    $product->setCategory(null); // product has no category, so set null
    ...
    

    I'm sorry I might have told you a lie.

    While doctrine does like above, two suggestions for solution:

    1. modify getter

      Other expression for "if the product has no category, returns empty Category instead"

      public function getCategory()
      {
          if (null !== $this->category) {
              return $this->category;
          }
      
          return new Category();
      }
      
    2. move such a "ifnull-then" logic into twig (as others say)

      in controller:

      public function showAction($id)
      {
          $product = $this->getDoctrine()->getRepository('AcmeStoreBundle:Product')->find($id);
          //$categoryName = $product->getCategory()->getName();
      
          return array('product' => $product);
      }
      

      in template:

      ...
      {{ product.category.name|default('no category') }}
      ...
      

      default('no category') does the trick. It returns 'no category' instead when:

      • when a error occurs internally ("get property from non-object" as you're facing)
      • if $product->getCategory()->getName() is falsy(empty string, null, 0, etc.)

    for me, I often prefer 2 over 1 because it's done with less code.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 chaquopy python 安卓
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 CSS实现渐隐虚线框
  • ¥15 有没有帮写代码做实验仿真的
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥30 vmware exsi重置后登不上
  • ¥15 易盾点选的cb参数怎么解啊
  • ¥15 MATLAB运行显示错误,如何解决?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容