Doctrine:类的对象无法转换为字符串 [英] Doctrine: Object of class User could not be converted to string
问题描述
PHP Catchable致命错误:类的对象无法转换为字符串在供应商/ doctrine / orm / lib / Doctrine / ORM / UnitOfWork.php第1337行
在我的系统用户可以在一对多关系中拥有许多权限。我设置了一个用户
和权限
实体。他们看起来像这样(我删除了一些注释,getter和setter以减少混乱):
class User {
/ **
* @ ORM\Column(name =user_id,type =integer,nullable = false)
* @ ORM\Id
* @ORM \GeneratedValue(strategy =IDENTITY)
* /
protected $ id;
public function getId()
{
return $ this-> id;
}
/ **
* @ ORM\OneToMany(targetEntity =Permission,mappedBy =user,cascade = {persist})
* /
protected $ permissions;
public function getPermissions()
{
return $ this-> permissions;
}
}
class许可{
/ **
* @ ORM\Column(name = user_id,type =integer)
* @ ORM\ManyToOne(targetEntity =User,inversedBy =permissions)
* /
protected $ user;
public function getUser()
{
return $ this-> user;
}
public function setUser($ user)
{
$ this-> user = $ user;
return $ this;
}
}
当我添加一个新的权限
到用户
:
$ permission = new Permission();
$ user-> getPermissions() - > add($ permission);
$ em-> persist($ user);
$ em-> flush();
这是我的堆栈跟踪的最后一位:
PHP 11. Doctrine\ORM\UnitOfWork-> persist()vendor / doctrine / orm / lib / Doctrine / ORM / EntityManager.php:565
PHP 12. Doctrine\ORM\UnitOfWork-> doPersist()vendor / doctrine / orm / lib / Doctrine / ORM / UnitOfWork.php:1555
PHP 13. Doctrine\ORM\UnitOfWork-> cascadePersist()vendor / doctrine / orm / lib / Doctrine / ORM / UnitOfWork.php:1615
PHP 14. Doctrine\ORM\UnitOfWork-> doPersist()vendor / doctrine / orm / lib / Doctrine / ORM / UnitOfWork.php:2169
PHP 15. Doctrine\ORM\UnitOfWork-> persistNew()vendor / doctrine / orm / lib / Doctrine / ORM / UnitOfWork.php:1597
PHP 16 。doctrine\ORM\UnitOfWork-> scheduleForInsert()doctrine / orm / lib / Doctrine / ORM / UnitOfWork.php:836
PHP 17. Doctrine\ORM\UnitOfWork-> addToIdentityMap()vendor /doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1157
PHP 18. implode()vendor / doctrine / orm / lib / Doctrine / ORM / UnitOfWork.php:1337
任何见解将不胜感激。 >
你的解决方案给了我一个线索,发生了什么。
即使你有实体和注释,Doctrine也无法理解实体之间的关系。当教义理解实体之间的关系时,它知道要调用哪些方法(即User :: getId()),但是否则它会尝试将发送的任何值转换为可用于查询数据库的标量值。这就是为什么它调用User的__toString函数,这就是为什么如果你返回id到toString,一切都从这里起作用。
这是可以的,但它是一个补丁,如果我们可以找到一个更好的解决方案,可能你不想保留它,因为它可能难以维护作为你的应用程序增长。
我可以看到,在您拥有的权限中:
/ **
* @ ORM\Column(name =user_id,type =integer)
* @ ORM\ManyToOne(targetEntity =User,inversedBy =permissions)
* /
protected $ user;
您应该删除 @ ORM\Column(type =integer
)
关于连接列,这不是强制性的,但您必须确保防护是您想要的。我们可以在这里阅读在我们详细介绍所有关联映射之前,您应该
注意到@JoinColumn和@JoinTable定义通常为$($)
< b $ b可选,并具有明智的默认值。一对一/多对一关联的连接
列的默认值如下所示:
name:< fieldname> _id
referencedColumnName:id
所以,它们将与显式相同:
/ **
* @ ORM\ManyToOne(targetEntity =User,inversedBy =permissions,cascade = {persist})
* @ ORM\JoinColumns({
* @ ORM\JoinColumn =user_id,referencedColumnName =id)
*})
* /
protected $ user;
所以应该查找一个列 user_id
在权限
表中,并将它与 User
表。我们假设这是可以的。
如果这是真的,那么在你的用户中,id不应该是user_id,但是id:
/ **
* @ ORM\Column(name =id,type =integer,nullable = false)
* @ ORM\Id
* @ ORM\GeneratedValue(strategy =IDENTITY)
* /
protected $ id;
或者如果列名实际上是user_id,那么User类可以,但是你必须改变连接列到@ ORM\JoinColumn(name =user_id,referencedColumnName =user_id)
我可以这么说。我不能尝试它,但如果你能给它一秒,我会很高兴。
I keep getting this error with Doctrine:
PHP Catchable fatal error: Object of class User could not be converted to string in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 1337
In my system users can have many permissions in a One to Many relationship. I have set up a User
and Permission
entity. They look like this (I removed some annotations, getters and setters to reduce clutter):
class User {
/**
* @ORM\Column(name="user_id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
public function getId()
{
return $this->id;
}
/**
* @ORM\OneToMany(targetEntity="Permission", mappedBy="user", cascade={"persist"})
*/
protected $permissions;
public function getPermissions()
{
return $this->permissions;
}
}
class Permission {
/**
* @ORM\Column(name="user_id", type="integer")
* @ORM\ManyToOne(targetEntity="User", inversedBy="permissions")
*/
protected $user;
public function getUser()
{
return $this->user;
}
public function setUser( $user )
{
$this->user = $user;
return $this;
}
}
The problem occurs when I add a new Permission
to a User
:
$permission = new Permission();
$user->getPermissions()->add( $permission );
$em->persist( $user );
$em->flush();
This is the last bit of my stack trace:
PHP 11. Doctrine\ORM\UnitOfWork->persist() vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:565
PHP 12. Doctrine\ORM\UnitOfWork->doPersist() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1555
PHP 13. Doctrine\ORM\UnitOfWork->cascadePersist() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1615
PHP 14. Doctrine\ORM\UnitOfWork->doPersist() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:2169
PHP 15. Doctrine\ORM\UnitOfWork->persistNew() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1597
PHP 16. Doctrine\ORM\UnitOfWork->scheduleForInsert() doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:836
PHP 17. Doctrine\ORM\UnitOfWork->addToIdentityMap() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1157
PHP 18. implode() vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1337
Any insight would be greatly appreciated.
Your solution gave me a clue of what is happening.
Even though you have the entities and the anotations, Doctrine is not being able to understand the relation between entities. When doctrine understands the relation between entities, it knows what methods to call (ie User::getId()) but otherwise, it tries to transform whatever you are sending to a scalar value that it can use to query the database. Thats why it is calling the __toString function of the User, and thats why if you return the id in toString, everything works from here.
This is ok, but its a patch, and probably you dont want to keep it if we can find a better solution, since it could be harder to maintain as your application grows.
What i can see, is that in Permissions you have:
/**
* @ORM\Column(name="user_id", type="integer")
* @ORM\ManyToOne(targetEntity="User", inversedBy="permissions")
*/
protected $user;
You should remove the @ORM\Column(type="integer"
)
About the join columns, it is not mandatory, but you have to be sure that the defauts, are what you want. As we can read here
Before we introduce all the association mappings in detail, you should note that the @JoinColumn and @JoinTable definitions are usually optional and have sensible default values. The defaults for a join column in a one-to-one/many-to-one association is as follows:
name: "<fieldname>_id"
referencedColumnName: "id"
so, they will be the same as an explicit:
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="permissions", cascade={"persist"})
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
* })
*/
protected $user;
So it is supposed to look for a column user_id
in the Permissions
table, and join it with the id
column of the User
table. We suppose that this is ok.
If this is true, then in your User, the id shouldnt be user_id, but id:
/**
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
Or if the column name is actually user_id, then the User class is ok, but you have to change the join column to @ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
That much i can say. I cannot try it know, but i will be glad if you can give it a second.
这篇关于Doctrine:类的对象无法转换为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!