如何解决PHP Doctrine:在自定义 DBAL 类型中使用相同类如 embbebed 和实体 ID的问题
我正在尝试在我的开发中实现 DDD 概念,但我在使用 PHP Doctrine ORM 时遇到了问题。
首先,我想告诉你我的设计。我有一个实体调用 Order,一个 Order 有一个 ProductId 属性。所以,我的班级模型是这样的:
Order.PHP
<?PHP
final class Order
{
protected OrderId $id;
protected ProductId $product_id;
protected ProductName $name;
public function setProductId($product_id)
{
$this->product_id = $product_id;
}
public function getProductId()
{
return $this->product_id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
}
Product.PHP
<?PHP
final class Product
{
protected ProductId $id;
protected ProductName $name;
protected $categories;
public function setId($id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function assignToCategory(Category $category)
{
$this->categories[] = $category;
}
public function getCategory()
{
return $this->categories;
}
}
映射 XML 是:
Order.dcm.xml
<!-- config/xml/Product.dcm.xml -->
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Order" table="orders">
<id name="id" type="order_id" column="id" length="36" />
<embedded name="product_id" class="ProductId" use-column-prefix="false" />
<embedded name="name" class="ProductName" use-column-prefix="false" />
</entity>
</doctrine-mapping>
Product.dcm.xml
<!-- config/xml/Product.dcm.xml -->
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Product" table="products">
<id name="id" type="product_id" column="id" length="36" />
<embedded name="name" class="ProductName" use-column-prefix="false" />
<many-to-many target-entity="Category" field="categories" />
</entity>
</doctrine-mapping>
如您所见,从一方面来说,对于 Order ORM 映射,我对 product_id 字段使用了 embeddable,另一方面,对于 Product ORM 映射,我对 id 字段使用了自定义类型。 这是产品的 id 自定义 DBAL 类型定义:
ProductIdType.PHP
<?PHP
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\StringType;
class ProductIdType extends StringType
{
public function getName(): string
{
return self::customTypeName();
}
public function convertToPHPValue($value,AbstractPlatform $platform)
{
$className = $this->typeClassName();
return new $className($value);
}
public function convertToDatabaseValue($value,AbstractPlatform $platform)
{
return $value->value();
}
public static function customTypeName(): string
{
return 'product_id';
}
protected function typeClassName(): string
{
return ProductId::class;
}
}
这里是需要订单 XML 映射的 ProductId XML 映射:
ProductId.dcm.xml
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<embeddable name="ProductId">
<field name="value" type="string" column="product_id" />
</embeddable>
</doctrine-mapping>
问题是当我尝试查找一个订单,然后在同一个脚本中尝试查找产品时。我认为问题在于同一类 ProductId 在同一脚本中用作可嵌入和自定义 DBAL 类型。但我希望有人能告诉我我是否正确,以及是否知道如何在不为 Order embedable 创建新类的情况下实现这一点。
我正在运行的脚本是:
show_product.PHP
<?PHP
require_once "bootstrap.PHP";
$id = $argv[1];
$order = $entityManager->find('Order',new OrderId($id));
if ($order === null) {
echo "No product found.\n";
exit(1);
}
echo print_r($order->getName());
$product = $entityManager->find('Product',new ProductId($id));
if ($product === null) {
echo "No product found.\n";
exit(1);
}
echo print_r($product->getName());
还有我的错误:
PHP Notice: Undefined offset: 0 in /home/dani/www/dev/doctrine2-test/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.PHP on line 769
PHP Stack trace:
PHP 1. {main}() /home/dani/www/dev/doctrine2-test/src/show_product.PHP:0
PHP 2. Doctrine\ORM\EntityManager->find() /home/dani/www/dev/doctrine2-test/src/show_product.PHP:16
PHP 3. Doctrine\ORM\UnitOfWork->getSingleIdentifierValue() /home/dani/www/dev/doctrine2-test/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.PHP:419
PHP 4. Doctrine\ORM\Mapping\ClassMetadata->getIdentifierValues() /home/dani/www/dev/doctrine2-test/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.PHP:3065
如果有人想查看所有代码,这里是 Github 存储库:https://github.com/daf111/doctrine2-test
非常感谢您抽出宝贵时间!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。