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

PHP 8.1升级后TYPO3 11.5.32自定义扩展starttime空值调用报错

问题根源与解决方案

核心问题

PHP 8.1的类型严格性升级,加上TYPO3 DataMapper的时间戳处理逻辑,导致数据库中starttime=0时,实体类的$starttime属性被设为null,调用getStarttime()后直接链式调用方法会触发"Call member function ... on null"错误。

具体原因

  1. TYPO3 DataMapper行为:当TCA配置eval='datetime,int'时,数据库中值为0的时间戳会被DataMapper转换为null,而非生成对应1970-01-01的DateTime对象。
  2. 类型声明不匹配:你的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 05:40:16