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

Symfony Serializer反序列化JSON至PHP类返回NULL问题求助

解决Symfony Serializer反序列化后属性为NULL的问题

问题根源

  1. 私有属性无访问器:Symfony Serializer的ObjectNormalizer默认无法直接操作私有属性,必须通过getter/setter、反射配置或元数据组件识别属性。
  2. 嵌套对象类型未被识别:Low/Medium/High类的私有属性和嵌套结构缺少元数据支持,Serializer无法自动实例化这些对象并赋值。
  3. 构造函数映射缺失:FeeClass的构造参数虽对应JSON键,但若无属性元数据,Serializer无法将JSON值绑定到构造参数。

解决方案

方案一:添加访问器并启用PropertyInfo组件(推荐生产环境)

  1. 为Low/Medium/High类添加getter/setter,确保属性可被Serializer访问:
class Low {
    private $networkFee;

    public function getNetworkFee(): ?string
    {
        return $this->networkFee;
    }

    public function setNetworkFee(string $networkFee): void
    {
        $this->networkFee = $networkFee;
    }
}

// Medium和High类复制上述代码,替换类名即可
  1. 安装Symfony PropertyInfo组件,用于识别属性类型和元数据:
composer require symfony/property-info
  1. 配置Serializer时注入PropertyInfo提取器:
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;

// 初始化属性信息提取器
$phpDocExtractor = new PhpDocExtractor();
$reflectionExtractor = new ReflectionExtractor();
$propertyInfoExtractor = new PropertyInfoExtractor(
    [$reflectionExtractor],
    [$phpDocExtractor, $reflectionExtractor],
    [$phpDocExtractor],
    [$reflectionExtractor]
);

// 配置Serializer
$normalizers = [new ObjectNormalizer(null, null, null, $propertyInfoExtractor)];
$encoders = [new JsonEncoder()];
$serializer = new Serializer($normalizers, $encoders);

// 执行反序列化
$parsed = $serializer->deserialize((string)$response->getBody(), FeeClass::class, 'json');

方案二:临时改为公开属性(仅用于测试)

若需快速验证,可将类属性改为公开(不推荐生产环境,违反封装原则):

class Low {
    public $networkFee;
}

class Medium {
    public $networkFee;
}

class High {
    public $networkFee;
}

class FeeClass {
    public $low;
    public $medium;
    public $high;
}

方案三:使用注解配置属性映射

  1. 安装注解组件:
composer require symfony/annotation
  1. 为类添加序列化注解:
use Symfony\Component\Serializer\Annotation\SerializedName;

class Low {
    /**
     * @SerializedName("networkFee")
     */
    private $networkFee;

    // 对应getter/setter
}

class FeeClass {
    /**
     * @SerializedName("low")
     */
    private $low;

    /**
     * @SerializedName("medium")
     */
    private $medium;

    /**
     * @SerializedName("high")
     */
    private $high;

    public function __construct(Low $low, Medium $medium, High $high) {
        $this->low = $low;
        $this->medium = $medium;
        $this->high = $high;
    }
}
  1. 配置Serializer启用注解加载:
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;

$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizers = [new ObjectNormalizer($classMetadataFactory)];
$encoders = [new JsonEncoder()];
$serializer = new Serializer($normalizers, $encoders);

内容的提问来源于stack exchange,提问作者Russo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 13:03:24