我目前正在发现symfony 2,并在这个精彩的框架上训练自己。所以我有新手问题......
我遵循本教程以管理与学说的关系: http://symfony.com/doc/current/book/doctrine.html
嗯,在我的测试中,我有一个问题和一个问题。
首先是问题: Symphony最佳实践表明,在其他.orm.yml文件中使用注释进行学说映射而不是yaml会更好。好,我完全赞同。 “使用注释很方便,并允许您在同一文件中定义所有内容”。因此,如果我们选择使用注释,我想我们不再需要.orm.yml映射文件了? 假设我有一个名为userType的表。我创建了一个实体类userType.php,并在此类中直接添加了带注释的映射信息。我尝试的任何东西,添加声明:
use Doctrine\ORM\Mapping as ORM;
或不在我的userType.php类中,symfony显示此错误:
No mapping file found named 'UserType.orm.yml' for class 'AppBundle\Entity\UserType
如果我不创建UserType.orm.yml文件。
所以这是我的问题:如果我们选择只使用注释,我们还需要一个.orm.yml映射文件吗?如果是,我们必须在此文件中添加的最小信息是什么?
第二点我的问题: 我的用户角色位于与用户表不同的表(userType)中。
+-------------------------------------------+-------------------------------------------+
|user | userType |
|id username password userType_id | userType_id label role |
|1 testuser something 1 | 1 Administrator ROLE_ADMIN |
+-------------------------------------------+-------------------------------------------+
所以我想我需要在user.php实体类中添加manyToOne关系(许多用户只能拥有相同的一个角色)。
所以我在User.orm.yml映射文件中添加了这些行
(…)
manyToOne:
userType:
targetEntity: UserType
joinColumn:
name: userType_id
referencedColumnName: userType_id
lifecycleCallbacks: { }
(…)
并在我的user.php实体类中声明了var userType,如下所示
/**
*
*/
private $userType;
这是我的userType.php实体类文件:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class UserType
{
/**
* @ORM\Id
* @ORM\Column(type="integer", name="userType_id")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", name="label")
*/
private $label;
/**
* @ORM\Column(type="simple_array", name="role")
*/
private $role;
public function getId()
{
return $this->id;
}
/**
*
*/
public function getLabel()
{
return $this->label;
}
public function setLabel($label)
{
$this->label = $label;
}
/**
*
*/
public function getRole()
{
return $this->role;
}
public function setRole($role)
{
$this->role = $role;
}
}
我的UserType.orm.yml文件:
AppBundle\Entity\UserType:
type: entity
table: userType
id:
id:
type: integer
id: true
column: userType_id
generator:
strategy: AUTO
fields:
label:
type: string
length: '150'
column: label
role:
type: simple_array
length: '100'
column: role
lifecycleCallbacks: { }
好吧,我的user.php实体的$ userType var似乎是一个包含userType数据的对象。 但是,如果我做了
var_export($this->userType, true);
$ userType对象的我得到了这个:
Proxies\__CG__\AppBundle\Entity\UserType::
__set_state(array( '__initializer__' => Closure::
__set_state(array( )), '__cloner__' =>
Closure::__set_state(array( )), '__isInitialized__' =>
false, 'id' => 1, 'label' => NULL, 'role' => NULL, ))
仅填充字段ID,其他为NULL。 如何在对象$ userType中获取标签和角色字段值?我的错是什么?
非常感谢你的帮助。
答案 0 :(得分:1)
感谢您的建议。他们帮助了我很多。
我解决了我的两个麻烦。
对于我的.orm文件问题:确实正如@chalasr建议的那样,在删除Resources / config / doctrine文件夹之后,Symphony停止向我显示有关缺少.orm文件的错误。通过关注@chalasr其他技巧,我设法停止使用orm文件。感谢。
但我还有其他问题(只有“id”字段填入$ userType对象,其他地方为NULL)。 我注意到$ userType对象没有初始化,实际上它是一个学说“lazy-loading-issue”。
这2个帖子帮助我解决了我的问题:
Get entities from a unidirectional many to many relation with Doctrine2 and Symfony2
doctrine2 association is not initialized
我在我的ManyToOne关系中添加了选项fetch =“EAGER”,现在所有$ userType对象字段都已完全填充。
这是我实际的ManyToOne关系(用注释制作; - ))
/**
* @ORM\ManyToOne(targetEntity="UserType", fetch="EAGER")
* @ORM\JoinColumn(name="users_types_id", referencedColumnName="users_types_id")
*/
private $userType;
这就是我如何获得角色字段值
/**
* Returns the roles or permissions granted to the user for security.
*/
public function getRoles()
{
$accessor_user_role = PropertyAccess::createPropertyAccessor();
$roles = $accessor_user_role->getValue($this->userType, 'role');
// guarantees that a user always has at least one role for security
if (empty($roles)) {
$roles[] = 'ROLE_USER';
}
return $roles;
}
我希望通过这种方式来尊重Symfony的良好做法。
非常感谢你的帮助。
答案 1 :(得分:0)
不,你必须在这两种格式之间做出选择。
您的实体存在许多问题。
您已省略@ORM\Table
语句,请使用:
/**
* @ORM\Entity
* @ORM\Table(name="user_types")
*/
class UserType
{
//...
}
然后,您必须重命名与其包含的类名称对应的文件。
您的班级名为UserType
,但包含该班级的文件名为userType.php
根据{{3}}
UserType.php
从文件系统加载时,每个命名空间分隔符都转换为DIRECTORY_SEPARATOR [...]
从文件系统加载时,完全限定的命名空间和类后缀为.php。
示例:App\AcmeBundle\Entity\User
将变为src/App/AcmeBundle/Entity/User.php
另外,我认为你在实体的声明中省略了命名空间的一部分,添加了bundle命名空间中缺少的第一部分(如PSR所述,它应该是{{1}之间的第一个文件夹的名称和你的src
目录。)
如果您在使用注释之前已开始使用YAML,请执行以下过程:
AppBundle
目录(或仅删除与实体对应的映射文件)。Resources/config/doctrine
php app/console doctrine:cache:clear-metadata
执行此操作后,通过执行以下操作,使用正确的映射更新数据库架构:
php app/console cache:clear