PHP 8.1升级后TYPO3 11.5.32自定义扩展starttime空值调用报错
问题根源与解决方案
核心问题
PHP 8.1的类型严格性升级,加上TYPO3 DataMapper的时间戳处理逻辑,导致数据库中starttime=0时,实体类的$starttime属性被设为null,调用getStarttime()后直接链式调用方法会触发"Call member function ... on null"错误。
具体原因
- TYPO3 DataMapper行为:当TCA配置
eval='datetime,int'时,数据库中值为0的时间戳会被DataMapper转换为null,而非生成对应1970-01-01的DateTime对象。 - 类型声明不匹配:你的
setStarttime()方法要求必须传入DateTime类型,但DataMapper需要传入null,导致setter无法被调用,最终$starttime属性保持初始的null状态。PHP 7.4对类型声明的检查更宽松,之前未触发问题,升级到8.1后严格校验暴露了这个矛盾。
修复步骤
1. 修改实体类的类型声明
允许属性和setter接受null,让DataMapper能正确赋值:
/** * @var DateTime|null */ protected $starttime; /** * Set start time * * @param DateTime|null $starttime start time */ public function setStarttime(?DateTime $starttime): void { $this->starttime = $starttime; }
2. 调用getStarttime()时增加null检查
因为返回值可能为null,必须先判断再调用DateTime的方法:
$entity = $this->repository->findByUid(1); $starttime = $entity->getStarttime(); if ($starttime !== null) { // 安全调用DateTime方法 $formattedTime = $starttime->format('Y-m-d H:i:s'); } else { // 处理无起始时间的场景 $formattedTime = '无起始时间'; }
3. 可选:调整TCA/数据库逻辑(若需保留0时间戳)
如果希望starttime=0对应1970-01-01的DateTime对象,可以修改TCA的eval配置,去掉int:
'eval' => 'datetime',
同时需同步调整数据库字段类型为datetime或timestamp,并适配实体类的时间处理逻辑。
内容的提问来源于stack exchange,提问作者Pekkonen
相关产品推荐
相关产品推荐

