正如我在标题中所说,我想将对象转换为ID(int/string(,并从ID向后转换为对象。通常我会处理实体关系,但在这种情况下,我不知道其他实体/捆绑包,它应该独立工作。
我想,我可以为此使用原则映射类型,但是如何注入我的自定义实体加载器?所以也许我可以使用回调来获取数据。
这是我的想法(伪代码(:
class User {
public function getId() { return 'IAmUserBobAndThisIdMyId'; }
}
class Meta {
private $user; // <== HERE I NEED THE MAGIC
public function setUser($user) { $this->user = user; }
}
$user = new User();
$meta = new Meta();
$meta->setUser($user);
$em->persist($meta); // <== HERE THE MAPPING TYPE SHOULD CONVERT THE ENTITY
知道我希望数据库中的实体是这样的:user:IAmUserBobAndThisIdMyId
向后:
$meta = $repository->findOneById(1); // HERE I NEED THE MAGIC AGAIN
$user = $meta->getUser();
echo $user->getId();
// output: IAmUserBobAndThisIdMyId
到目前为止,如此简单...但现在我需要一些逻辑和数据库访问权限来还原该实体。加载很容易,但是如何将其注入到我的映射类型类中?
我阅读了原则文档,我想知道,我是否可以使用我通过参数从AbstractPlatform $platform
获得的事件管理器。或者有更好的方法吗?
你可以尝试这样的事情,但我没有测试这个。此外,还可以使用 postLoad 和 postPersist/postUpdate 事件将 User 实体转换为整数并返回。
学说.yaml
doctrine:
dbal:
...
types:
user: AppDoctrineDBALTypeUserType
...
用户类型.php
<?php
namespace AppDoctrineDBALType;
use DoctrineDBALPlatformsAbstractPlatform;
use DoctrineDBALTypesIntegerType;
use AppRepositoryUserRepository;
use AppEntityUser;
class UserType extends IntegerType
{
const NAME = 'user';
private $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return $this->userRepository->find($value);
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
if (!$value instanceof User) {
throw new InvalidArgumentException("Invalid value");
}
return $value->getId();
}
public function getName()
{
return self::NAME;
}
}
我找到了一个合适的解决方案,而无需破解任何类来注入一些服务。类型映射类触发事件,转换在外部处理。
class EntityString extends Type
{
// ...
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return $this->dispatchConverterCall($platform, TypeMapperEventArgs::TO_PHP_VALUE, $value);
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return $this->dispatchConverterCall($platform, TypeMapperEventArgs::TO_DB_VALUE, $value);
}
protected function dispatchConverterCall(AbstractPlatform $platform, $name, $value)
{
$event = new TypeMapperEventArgs($name, $value);
$platform->getEventManager()->dispatchEvent(TypeMapperEventArgs::NAME, $event);
return $event->getResult();
}
// ...
}
可能有一些更好的解决方案,但目前代码可以满足我的需要。