fix(upgrade): 修复 L13/PHP8.4 升级回归的 3 处致命异常 + 收敛动态路由暴露面

巡检全量 323 接口 + laravel.log PHP 致命异常普查发现:

- Base::getSchemeAndHost(): 非请求上下文(Task/导出闭包)request() 非
  Request 实例,调 getHttpHost() 致命错误(导出超期任务等)。加 instanceof 守卫。
- FileController::office__token(): php-jwt v7 强制 array payload,
  config 缺失为 null 触发 TypeError。校验为数组,否则 retError。
- DialogController::msg__translation(): 空 language 传入
  Doo::getLanguages(bool|string) 触发 TypeError。前置拦截空值。
- InvokeController: 动态路由改为仅暴露 public 方法,protected/private
  视为内部方法返回 404,堵住内部辅助方法被裸访问触发 ArgumentCountError。
- ApproveController: 6 个内部辅助方法(getProcessById 等)收敛为 protected。

验证: 复扫 323 接口 0 个 5xx,phpstan 无错误,真 public 端点回归正常。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
kuaifan 2026-06-13 04:05:31 +00:00
parent 6bbcb702dc
commit 8d9082f7a1
5 changed files with 15 additions and 9 deletions

View File

@ -987,7 +987,7 @@ class ApproveController extends AbstractController
return Base::retSuccess('success');
}
function getStateDescription($state)
protected function getStateDescription($state)
{
$state_map = array(
0 => '全部',
@ -1021,7 +1021,7 @@ class ApproveController extends AbstractController
}
// 处理参与人返回数据
public function handleParticipant($process, $participant)
protected function handleParticipant($process, $participant)
{
// 如果空
if (empty($participant)) {
@ -1059,7 +1059,7 @@ class ApproveController extends AbstractController
}
// 审批机器人消息
public function approveMsg($type, $dialog, $botUser, $toUser, $process, $action = null)
protected function approveMsg($type, $dialog, $botUser, $toUser, $process, $action = null)
{
$data = [
'id' => $process['id'],
@ -1139,7 +1139,7 @@ class ApproveController extends AbstractController
}
// 根据ID获取流程
public function getProcessById($id)
protected function getProcessById($id)
{
$data['id'] = intval($id);
$ret = Ihttp::ihttp_get($this->flow_url . "/api/v1/workflow/process/findById?" . http_build_query($data));
@ -1191,7 +1191,7 @@ class ApproveController extends AbstractController
}
// 处理流程节点返回是否有抄送人
public function handleProcessNode($process)
protected function handleProcessNode($process)
{
// 获取流程节点
$process_node = $process['node_infos'];
@ -1209,7 +1209,7 @@ class ApproveController extends AbstractController
}
// 根据ID查询流程实例的参与者所有
public function getUserProcessParticipantById($id)
protected function getUserProcessParticipantById($id)
{
$data['procInstId'] = intval($id);
$ret = Ihttp::ihttp_get($this->flow_url . "/api/v1/workflow/identitylink/findParticipantAll?" . http_build_query($data));

View File

@ -2125,6 +2125,9 @@ class DialogController extends AbstractController
$msg_id = intval(Request::input("msg_id"));
$force = intval(Request::input("force"));
$language = Base::inputOrHeader('language');
if (empty($language)) {
return Base::retError("参数错误");
}
$targetLanguage = Doo::getLanguages($language);
//
if (empty($targetLanguage)) {

View File

@ -737,6 +737,9 @@ class FileController extends AbstractController
File::isNeedInstallApp('office');
//
$config = Request::input('config');
if (!is_array($config)) {
return Base::retError('参数错误');
}
$token = \Firebase\JWT\JWT::encode($config, config('app.key') ,'HS256');
return Base::retSuccess('成功', [
'token' => $token

View File

@ -24,8 +24,8 @@ class InvokeController extends BaseController
if ($action) {
$app .= "__" . $action;
}
// 接口不存在
if (!method_exists($this, $app)) {
// 接口不存在(仅 public 方法可作为端点protected/private 为内部方法,不暴露为路由)
if (!method_exists($this, $app) || !(new \ReflectionMethod($this, $app))->isPublic()) {
$msg = "404 not found (" . str_replace("__", "/", $app) . ").";
return Base::ajaxError($msg);
}

View File

@ -851,7 +851,7 @@ class Base
// 优先用当前请求的协议+主机getScheme() 会经 TrustProxies 采信 X-Forwarded-Proto
// 从而正确识别 httpshost 取自 Host 头(不信 X-Forwarded-Host避免 Host 注入)
$request = request();
if ($request && $request->getHttpHost()) {
if ($request instanceof \Illuminate\Http\Request && $request->getHttpHost()) {
return $request->getSchemeAndHttpHost();
}
// 非请求上下文Task/命令行等)的兜底