diff --git a/application/common/controller/Backend.php b/application/common/controller/Backend.php index 9f9df101d72d3dabf3794cc6878f615708dcb878..a48d814d2fed457c7f1f8e3023fd103a11fbbc0a 100644 --- a/application/common/controller/Backend.php +++ b/application/common/controller/Backend.php @@ -7,6 +7,7 @@ use think\Config; use think\Controller; use think\Hook; use think\Lang; +use think\Db; use think\Loader; use think\Model; use think\Session; @@ -494,6 +495,18 @@ class Backend extends Controller $primarykey = $this->request->request("keyField"); //主键值 $primaryvalue = $this->request->request("keyValue"); + // keyValue 与 keyField 必须成对合法,否则退回普通搜索,避免出现 [null => ...] 等异常条件 + if ($primaryvalue === '') { + $primaryvalue = null; + } + $hasPrimaryInit = false; + if ($primaryvalue !== null) { + if (is_string($primarykey) && preg_match('/^[a-zA-Z0-9_\-]+$/i', $primarykey) === 1) { + $hasPrimaryInit = true; + } else { + $primaryvalue = null; + } + } //搜索字段 $searchfield = (array)$this->request->request("searchField/a"); //自定义搜索条件 @@ -511,8 +524,8 @@ class Backend extends Controller } $field = $field ? $field : 'name'; - //如果有primaryvalue,说明当前是初始化传值 - if ($primaryvalue !== null) { + //如果有 primaryvalue 且 keyField 合法,说明当前是初始化传值 + if ($hasPrimaryInit) { $where = [$primarykey => ['in', $primaryvalue]]; $pagesize = 999999; } else { @@ -556,17 +569,26 @@ class Backend extends Controller $fields = is_array($this->selectpageFields) ? $this->selectpageFields : ($this->selectpageFields && $this->selectpageFields != '*' ? explode(',', $this->selectpageFields) : []); - //如果有primaryvalue,说明当前是初始化传值,按照选择顺序排序 - if ($primaryvalue !== null && preg_match("/^[a-z0-9_\-]+$/i", $primarykey)) { - $primaryvalue = array_unique(is_array($primaryvalue) ? $primaryvalue : explode(',', $primaryvalue)); - //修复自定义data-primary-key为字符串内容时,给排序字段添加上引号 - $primaryvalue = array_map(function ($value) { - return '\'' . $value . '\''; - }, $primaryvalue); - - $primaryvalue = implode(',', $primaryvalue); - - $this->model->orderRaw("FIELD(`{$primarykey}`, {$primaryvalue})"); + // 初始化传值时按 FIELD 顺序排序(值使用 PDO 转义,防止注入) + if ($hasPrimaryInit && is_string($primarykey) && preg_match('/^[a-zA-Z0-9_\-]+$/i', $primarykey) === 1) { + $primaryValueList = is_array($primaryvalue) ? $primaryvalue : explode(',', (string)$primaryvalue); + $primaryValueList = array_values(array_unique(array_filter( + $primaryValueList, + static function ($v) { + return $v !== null && $v !== ''; + } + ))); + if ($primaryValueList !== []) { + $pdo = Db::connect()->getPdo(); + $quoted = []; + foreach ($primaryValueList as $value) { + $quoted[] = $pdo->quote((string)$value); + } + $columnExpr = '`' . str_replace('.', '`.`', $primarykey) . '`'; + $this->model->orderRaw('FIELD(' . $columnExpr . ', ' . implode(',', $quoted) . ')'); + } else { + $this->model->order($order); + } } else { $this->model->order($order); } @@ -592,7 +614,7 @@ class Backend extends Controller }, $result); $list[] = $result; } - if ($istree && !$primaryvalue) { + if ($istree && !$hasPrimaryInit) { $tree = Tree::instance(); $tree->init(collection($list)->toArray(), 'pid'); $list = $tree->getTreeList($tree->getTreeArray(0), $field);