我有一个我正在研究的项目,它使用了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
而不是包含兴趣的可迭代。
我在注释中的关系是否有问题?或者我只是不明白如何打电话来获取利益?我真的被困在这里了。任何帮助都会很棒,如果我发布任何其他信息以便更清楚,请告诉我。谢谢!
我在关系中进行了更改,以便每个订阅只能有一个订阅者。当我查询订阅时,我现在得到这个:
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。
答案 0 :(得分:0)
问题
在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;
并在costructor中删除此行。
$this->interests = new ArrayCollection();
创建ManyToMany关系的另一种方式。这意味着订阅具有倍数兴趣,并且兴趣具有倍数订阅。如果是这样的话,我可以更新这个答案,为它创建一个例子。