php - 调用未定义的方法 Closure::getName()

标签 php entity-framework doctrine-orm

背景

我有一个正在进行的项目,它使用 Doctrine 2。我已经创建了实体,定义了关系,将测试数据放入数据库中,并且在它的测试部分。我对 Doctrine 并不陌生(因为使用了 Symfony 框架),但我对单独使用 Doctrine 组件并不陌生——这就是它。我不知道这是否有任何影响,但我想明确表示这不是 Symfony 项目。

实体

兴趣

/**
 * Class Interest
 * @ORM\Entity()
 * @ORM\Table(name="interest", uniqueConstraints={
 *   @ORM\UniqueConstraint(name="interest_name", columns={"name"})
 * })
 */
class Interest {
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", unique=TRUE, nullable=FALSE)
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(name="description", type="string")
     */
    private $description;

    /**
     * @var array
     *
     * @ORM\OneToMany(targetEntity="Subscription", mappedBy="interests", cascade={"persist", "remove"}, orphanRemoval=TRUE)
     */
    private $subscribers;

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

订阅

/**
 * Class Subscription
 * @ORM\Entity()
 * @ORM\Table(name="subscription")
 */
class Subscription {
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var array
     *
     * @ORM\ManyToOne(targetEntity="Interest", inversedBy="subscribers")
     * @ORM\JoinColumn(name="interest_id", referencedColumnName="id", nullable=FALSE)
     */
    private $interests;

    /**
     * @var string
     *
     * @ORM\ManyToOne(targetEntity="Subscriber", inversedBy="interests")
     * @ORM\JoinColumn(name="subscriber_id", referencedColumnName="id", nullable=FALSE)
     */
    private $subscriber;

    /**
     * @var string
     *
     * @ORM\Column(name="interest_date", type="datetime")
     */
    private $subscribed_on;

    public function __construct() {
        $this->subscribed_on = new \DateTime("now");
        $this->interests = new ArrayCollection();
    }

订阅者

/**
 * Class Subscriber
 * @ORM\Entity()
 * @ORM\Table(name="subscriber", uniqueConstraints={
 *   @ORM\UniqueConstraint(name="subscriber_email", columns={"email"})
 * })
 */
class Subscriber {
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="first_name", type="string")
     */
    private $first_name;

    /**
     * @var string
     *
     * @ORM\Column(name="last_name", type="string")
     */
    private $last_name;

    /**
     * @var string
     *
     * @ORM\Column(name="email", type="string", unique=TRUE, nullable=FALSE)
     */
    private $email;

    /**
     * @var array
     * 
     * @ORM\OneToMany(targetEntity="Subscription", mappedBy="subscriber", cascade={"persist", "remove"}, orphanRemoval=TRUE)
     */
    private $interests;

    /**
     * @var boolean
     *
     * @ORM\Column(name="is_subscribed", type="boolean")
     */
    private $is_subscribed;

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

测试

然后为了测试我使用这个简单脚本的关系:

$subscriptionRepo = $entityManager->getRepository( 'Subscribr\Entity\Subscription' );
$subscriptions = $subscriptionRepo->findAll();

foreach ($subscriptions as $subscription) {
    echo sprintf( "-%s\n", $subscription->getSubscriber()->getEmail() );
    $interests = $subscription->getInterests();
    foreach ($interests as $interest) {
        echo sprintf( "--%s\n", $interest->getName() );
    }
}

问题

解释器一直进入第二个循环的内部,并因以下异常而失败:

C:\xampp\htdocs\www\public_html\playground\subscribr>php list_subscriptions.php
-testemail@domain.com
PHP Fatal error:  Call to undefined method Closure::getName() in C:\xampp\htdocs\www\public_html\playground\subscribr\list_subscriptions.php on line 17
PHP Stack trace:
PHP   1. {main}() C:\xampp\htdocs\www\public_html\playground\subscribr\list_subscriptions.php:0

我已经进行了大量的 Google 搜索和 SO 搜索,但无法弄清楚为什么 Subscriber 实体可以很好地呈现电子邮件,但 Interest 实体返回一个 Closure 而不是包含兴趣的可迭代对象。

我的注释中的关系有问题吗?或者我只是不明白如何打电话来获得利益?我真的被困在这里了。任何帮助都会很棒,如果我可以发布其他任何内容以使其更清楚,请告诉我。谢谢!

编辑1

我对关系进行了更改,以便每个订阅只能有一个订阅者。当我查询订阅时,我现在得到这个:

C:\xampp\htdocs\www\public_html\playground\subscribr>php list_subscriptions.php
-testemail@tester.com
--Magazine
-testemail@tester.com
--Newsletter
-testemail@tester.com
--Promotions
-testemail@tester.com
--Email
-testemail2@tester.com
--Magazine
-testemail2@tester.com
--Promotions
-testemail3@tester.com
--Newsletter
-testemail3@tester.com
--Email
-testemail4@tester.com
--Magazine
-testemail4@tester.com
--Promotions
-testemail4@tester.com
--Email
-testemail5@tester.com
--Magazine
-testemail6@tester.com
--Newsletter
-testemail7@tester.com
--Promotions
-testemail9@tester.com
--Promotions
-testemail10@tester.com
--Newsletter

现在我很好奇将它们合并是否正确,或者这是否是利益和订户的工作。所以I'll open another question .

最佳答案

问题

在 Subscription 类中,您创建了 ManyToOne 关系。这意味着多个订阅可以有一个兴趣。但这也意味着每个订阅都有一个且只有一个兴趣。您将其创建为数组。

/**
 * @var array
 *
 * @ORM\ManyToOne(targetEntity="Interest", inversedBy="subscribers")
 * @ORM\JoinColumn(name="interest_id", referencedColumnName="id", nullable=FALSE)
 */
private $interests;

解决方案

解决此问题的一种可能解决方案:您需要在订阅中使用单一兴趣。

/**
 * @var Interest
 *
 * @ORM\ManyToOne(targetEntity="Interest", inversedBy="subscribers")
 * @ORM\JoinColumn(name="interest_id", referencedColumnName="id", nullable=FALSE)
 */
private $interest;

并在构造函数中删除这一行。

    $this->interests = new ArrayCollection();

另一种方法是创建多对多关系。这意味着一个订阅有多个兴趣,一个兴趣有多个订阅。如果是这种情况,我可以更新此答案并为其创建一个示例。

关于php - 调用未定义的方法 Closure::getName(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40872390/

相关文章:

symfony - Doctrine2一对多,自引用关系

php - 2 mysql查询中的where语句

php - 错误 : Transport config "Smtp" is missing in cakephp 3. x

PHP - 数据访问并发测试

c# - Entity Framework 无法在 Web.config 中找到连接字符串

c# - 使用 Moq 更新、删除单元测试的方法

tree - 教义2 : Tree - Nestedset and InnoDB

php - 相同的字符串比较不起作用mysql

c# - 在 Entity Framework 中删除聚合根的子对象

doctrine - 在 Doctrine2/Symfony2 中插入忽略重复条目