【问题标题】:Symfony2: Doctrine throws exception "Fatal error: Call to a member function add() on a non-object"Symfony2:Doctrine 抛出异常“致命错误:在非对象上调用成员函数 add()”
【发布时间】:2014-01-22 01:05:40
【问题描述】:

我无法弄清楚为什么我的关联不起作用。

我得到的错误如下:

Fatal error: Call to a member function add() on a non-object in http://localhost/Projects/clariture/app/src/Clariture/Models/Channel.php on line 32

我的代码如下:

<?php

namespace Clariture\Classes;

class Entity {

    /**
     * @Id @Column(type="integer")
     * @GeneratedValue
     */
    protected $id;

    /**
     * @Column(type="integer")
     */
    protected $dateCreated = 0;

    /**
     * @Column(type="integer")
     */
    protected $dateUpdated = 0;

    /**
     * @param string $name
     */
    public function __get($name)
    {
        return $this->$name;
    }

    /**
     * @param string $name
     * @param mixed $value
     */
    public function __set($name, $value) {

        $this->$name = $value;

    }

}

<?

namespace Clariture\Entities;
/**
 * @Entity
 * @Table(name="Channels")
 */
class Channel extends \Clariture\Classes\Entity {

    /**
     * @Column(type="string", length=140)
     */
    protected $name;

    /**
     * @Column(type="string", length=255)
     */
    protected $type;

    /**
     * @Column(type="string", length=255)
     */
    protected $token;

    /**
     * @OneToMany(targetEntity="ServiceLine", mappedBy="channels")
     */
    protected $serviceLine;

}

<?

namespace Clariture\Entities;
/**
 * @Entity
 * @Table(name="ServiceLines")
 */
class ServiceLine extends \Clariture\Classes\Entity {

    /**
     * @Column(type="string", length=140)
     */
    protected $name;

    /**
     * @Column(type="string", length=45)
     */
    protected $code;

    /**
     * @Column(type="boolean")
     */
    protected $active;

    /**
     * @ManyToOne(targetEntity="Channel", inversedBy="serviceLine")
     */
    protected $channels;

    /**
     * @OneToMany(targetEntity="Group", mappedBy="serviceLines")
     **/
    protected $group;

    public function __construct() {

        $this->channels = new \Doctrine\Common\Collections\ArrayCollection();

    }

}

<?php

namespace Clariture\Controllers;

use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;

class ChannelController extends \Clariture\Classes\Controller {

    public $roles = [_USER_ROLE_ADMIN];

    public function create($channelType) {

        $accessToken = $this->request->get('accessToken');
        $serviceLineId = $this->request->get('serviceLineId');
        $groupId = $this->request->get('groupId');

        $this->monolog->addDebug('accessToken: ' . $accessToken);
        $this->monolog->addDebug('serviceLineId: ' . $serviceLineId);

        $name = null;
        /* get the extended access token */
        switch($channelType) {

            default:
            case _CHANNEL_TYPE_FACEBOOK:
                $this->facebook->setAccessToken($accessToken);
                $this->facebook->setExtendedAccessToken();
                $accessToken = $this->facebook->getAccessToken();
                $user = $this->facebook->api('/me');
                $name = $user['name'];
            break;

        }

        $group = $this->em->find('Clariture\Entities\Group', $groupId);     
        $serviceLine = $this->em->find('Clariture\Entities\ServiceLine', $serviceLineId);

        $channel = new \Clariture\Entities\Channel;
        $channel->token = $accessToken;
        $channel->type = $channelType;
        $channel->name = $name;
        $channel->serviceLine = $serviceLine;

        $channel->group = $group;
        $channel->dateCreated = time();
        $serviceLine->channels->add($channel);
        $group->channels->add($channel);
        // $this->monolog->addDebug('serviceLine: ' . print_r($serviceLine, 1));

        $this->em->persist($channel);
        $this->em->flush();

    }

<?php

namespace Clariture\Entities;

use Doctrine\Common\Collections\ArrayCollection;

/**
 * @Entity
 * @Table(name="groups")
 */
class Group extends \Clariture\Classes\Entity {

    /**
     * @Id @Column(type="integer")
     * @GeneratedValue
     */
    protected $id;

    /**
     * @Column(type="string", unique=true, length=140)
     */

    protected $name;

    /**
     * @OneToMany(targetEntity="Group", mappedBy="parent")
     **/
    private $children;

    /**
     * @ManyToOne(targetEntity="Group", inversedBy="children")
     * @JoinColumn(name="parent_id", referencedColumnName="id")
     **/
    private $parent;

    /**
     * @ManyToOne(targetEntity="ServiceLine", inversedBy="group")
     **/
    protected $serviceLines;

    /**
     * @ManyToOne(targetEntity="Channel", inversedBy="group")
     **/
    protected $channels;

    public function __construct() {

        $this->children = new \Doctrine\Common\Collections\ArrayCollection();
        $this->channels = new \Doctrine\Common\Collections\ArrayCollection();

    }

}

【问题讨论】:

  • 异常在第 32 行的 Clariture\Models\Channel 中指出错误,但您没有将此类添加到您的问题中。你想做什么?坚持一个新实体?更新现有的?请提供更多信息。
  • 抱歉,添加了那个类:)
  • 奇怪的活动记录模式顺便说一句。 - 你确定你知道你在那里做什么吗?无论如何,我的回答应该可以解决您的问题:)
  • 怪异?你能详细说明一下吗?
  • 请不要误会我的意思——我只是想帮忙 :) “怪异”的目标是你的代码风格——没有设置器,奇怪的对象实例化链,混合 php 5.4 风格 @987654324 @ 和旧的array() 语法在这里和那里......看起来很混合,并且带有教义的活动记录模式并不那么容易实现。

标签: php symfony orm doctrine-orm doctrine


【解决方案1】:

关键代码应该是:

$serviceLine->channels->add($channel);
$group->channels->add($channel);

$serviceLine$group 未正确实例化,导致 $serviceLine-&gt;channels$group-&gt;channels 在您尝试调用 add(..) 时未持有 Collection 的实例。

确保你有...

public function __construct 
{
    $this->channels = new ArrayCollection();
}

...在您的 ServiceLineGroup 类中,并使用 new 语法创建对象。

【讨论】:

  • 如果你看的话,ServiceLine 实体实际上已经在构造函数中有那个位。此外,我尝试关联的 ServiceLine 和 Group 对象已经存在于数据库中。仅供参考,$serviceLine->get() 返回实体(我的频道模型的第 14 行)
  • 第 32 行究竟是哪一行出现异常?
  • 第 32 行是 $serviceLine-&gt;channels-&gt;add($channel);
猜你喜欢
  • 1970-01-01
  • 2013-10-29
  • 1970-01-01
  • 2019-05-21
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
  • 2012-05-30
  • 2016-08-30
相关资源
最近更新 更多