Doctrine:类的对象无法转换为字符串 [英] Doctrine: Object of class User could not be converted to string

查看:116
本文介绍了Doctrine:类的对象无法转换为字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆