问题描述
我正在尝试在我的开发中实现 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 (将#修改为@)