You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用Doctrine flush保存X实体时遇UUID类型转换错误,Stringable未被识别

Doctrine flush时Stringable UUID类类型转换错误的解决方法

调用Doctrine的flush()保存X实体时触发类型转换错误:

Could not convert PHP value of type X to type uuid. Expected one of the following types: null, string, Symfony\Component\Uid\AbstractUid

相关代码:

final class X extends MyUuid
{

}
abstract class MyUuid implements \Stringable
{
    final public function __construct(protected string $value)
    {
        
    }

    public function __toString(): string
    {
        return $this->value;
    }
}

问题原因

Doctrine的UUID类型转换器只会检查变量的实际类型是否匹配(null/string/AbstractUid实例),不会自动调用__toString()将Stringable对象转换为字符串。你的X类实例的类型是X,不是string,因此触发类型检查失败。

解决方案

方案1:自定义Doctrine类型

创建专门的Doctrine类型来处理你的MyUuid/X类,让Doctrine明确如何在PHP对象和数据库值之间转换:

  1. 实现自定义类型类:
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;

class MyUuidType extends Type
{
    public const NAME = 'my_uuid';

    public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
    {
        // 复用数据库原生UUID类型的声明
        return $platform->getGuidTypeDeclarationSQL($column);
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string
    {
        if ($value instanceof MyUuid) {
            return (string) $value;
        }
        return $value;
    }

    public function convertToPHPValue($value, AbstractPlatform $platform): ?MyUuid
    {
        if (is_string($value) && !empty($value)) {
            return new X($value);
        }
        return null;
    }

    public function getName(): string
    {
        return self::NAME;
    }

    public function requiresSQLCommentHint(AbstractPlatform $platform): bool
    {
        return true;
    }
}
  1. 注册自定义类型(以Symfony为例,修改config/packages/doctrine.yaml):
doctrine:
    dbal:
        types:
            my_uuid: App\Doctrine\Type\MyUuidType
  1. 在实体中使用该类型:
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class YourEntity
{
    /**
     * @ORM\Column(type="my_uuid")
     */
    private X $uuid;
}

方案2:使用转换回调

在实体映射中添加转换回调,手动实现PHP对象与数据库值的转换:

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class YourEntity
{
    /**
     * @ORM\Column(type="uuid")
     * @ORM\ConvertToDatabaseValue(callback="static::convertXToUuidString")
     * @ORM\ConvertToPHPValue(callback="static::convertUuidStringToX")
     */
    private X $uuid;

    public static function convertXToUuidString(X $value): string
    {
        return (string) $value;
    }

    public static function convertUuidStringToX(string $value): X
    {
        return new X($value);
    }
}

方案3:继承Symfony的AbstractUid

如果可以修改基类,让MyUuid继承Symfony\Component\Uid\AbstractUid,直接符合Doctrine UUID类型的要求:

abstract class MyUuid extends \Symfony\Component\Uid\AbstractUid
{
    public function __construct(string $value)
    {
        parent::__construct($value);
    }
}

这样X类作为AbstractUid的子类,实例会被Doctrine自动识别,无需额外转换。

内容的提问来源于stack exchange,提问作者Carlos 2V

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 09:47:15