PHPstan报错:无法访问array|EntityInterface|null的$work属性及参数不匹配
解决PHPstan检测到的CakePHP删除方法类型错误
我在开发Web应用时遵循PHPstan规范,以下是我的CakePHP delete方法代码,实际可运行但触发了两个PHPstan类型错误:
/** * AJAX: deletes a work file * * @return \Cake\Http\Response|false */ public function delete() { $this->autoRender = false; $this->viewBuilder()->setLayout('ajax'); $this->request->allowMethod(['post', 'delete']); $data = $this->request->getData(); $data = is_array($data) ? $data : [$data]; $workFile = $this->WorkFiles->find('all') ->where(['WorkFiles.id' => $data['id']]) ->contain(['Works']) ->first(); $res = [ 'status' => 'error', 'message' => __('The file could not be deleted. Please, try again.'), 'class' => 'alert-error', ]; if ($workFile->work->anagraphic_id == $this->authAnagraphics['id']) { // error #1 if ($this->WorkFiles->delete($workFile)) { // error #2 $res = [ 'status' => 'success', 'message' => __('File successfully deleted.'), 'class' => 'alert-success', ]; } } return $this->response->withStringBody((string)json_encode($res)); }
触发的PHPstan错误
- 错误1:
[phpstan] Cannot access property $work on array|Cake\Datasource\EntityInterface|null. - 错误2:
[phpstan] Parameter #1 $entity of method Cake\ORM\Table::delete() expects Cake\Datasource\EntityInterface, array|Cake\Datasource\EntityInterface|null given.
问题原因
find()->first()的返回值可能是null(未找到对应记录)、Cake\Datasource\EntityInterface实例,PHPstan无法确定$workFile一定是实体对象,直接访问$workFile->work会触发类型不匹配错误。Table::delete()方法要求传入EntityInterface实例,但$workFile可能为null,参数类型不匹配导致报错。
修复方案
先校验$workFile的有效性,确保它是实体实例后再进行后续操作:
/** * AJAX: deletes a work file * * @return \Cake\Http\Response|false */ public function delete() { $this->autoRender = false; $this->viewBuilder()->setLayout('ajax'); $this->request->allowMethod(['post', 'delete']); $data = $this->request->getData(); $data = is_array($data) ? $data : [$data]; // 先校验请求数据是否包含id,避免数组键不存在的警告 if (!isset($data['id'])) { $res = [ 'status' => 'error', 'message' => __('Invalid request data.'), 'class' => 'alert-error', ]; return $this->response->withStringBody((string)json_encode($res)); } $workFile = $this->WorkFiles->find('all') ->where(['WorkFiles.id' => $data['id']]) ->contain(['Works']) ->first(); $res = [ 'status' => 'error', 'message' => __('The file could not be deleted. Please, try again.'), 'class' => 'alert-error', ]; // 先判断$workFile是否为合法实体实例 if ($workFile instanceof \Cake\Datasource\EntityInterface) { // 确保关联的work数据已加载 if (isset($workFile->work) && $workFile->work->anagraphic_id == $this->authAnagraphics['id']) { if ($this->WorkFiles->delete($workFile)) { $res = [ 'status' => 'success', 'message' => __('File successfully deleted.'), 'class' => 'alert-success', ]; } } } return $this->response->withStringBody((string)json_encode($res)); }
额外优化
- 增加了
$data['id']的存在性校验,避免PHP的Undefined array key警告。 - 增加了
$workFile->work的存在性判断,防止关联数据未正确加载时的错误。
内容的提问来源于stack exchange,提问作者ToX 82
相关产品推荐
相关产品推荐

