RESTful extraPatterns 不生效的主因是路由顺序或配置错误:规则需排在基础规则后、使用 yii\rest\UrlRule 类、键名格式为“METHOD action”(大小写敏感、空格不可少)、pattern 要含占位符才支持带 ID 动作,且控制器须继承 yii\rest\ActiveController。

RESTful_extraPatterns 里自定义动作不生效?先看路由是否被前置规则拦截
Yii2 的 UrlRule 在启用 enablePrettyUrl 后,会按数组顺序逐条匹配;一旦某条规则命中,后续规则(包括你写的 extraPatterns)就完全不会执行。常见现象是:GET /users/123/export 返回 404,但 POST /users/123/export 却能进控制器 —— 实际上是被默认的 ['GET' => 'view'] 规则提前吃掉了 export 当作 ID 解析。
- 确保你的
extraPatterns所在的规则排在 RESTful 基础规则(如'pattern' => 'users')之后,且没有更宽泛的通配规则(比如'pattern' => '<controller:>/<action:>'</action:></controller:>)挡在前面 - 用
yii\rest\UrlRule::class而非普通UrlRule,否则extraPatterns字段直接被忽略 - 调试时临时加
'suffix' => '.json'或固定后缀,避免和 ID 冲突(例如'export.json')
extraPatterns 的键名必须是 HTTP 方法 + 空格 + 动作名,不能带斜杠
很多人写成 'GET export' => 'export' 是对的,但写成 'GET /export' 或 'get export' 就失效。Yii2 内部用 preg_match('/^([A-Z]+)\s+(.+)$/') 解析键,大小写敏感、空格不可省略、路径前缀不参与匹配 —— 它只管“方法 + 动作名”这个组合是否与当前请求一致。
- 合法键:
'POST activate'、'DELETE deactivate'、'GET index-export' - 非法键:
'post activate'(小写)、'POST/activate'(缺空格)、'GET /export'(多了/) - 动作名(右边值)对应控制器里的 public 方法名,如
actionExport(),注意驼峰转短横线规则:actionIndexExport()→'index-export'
自定义动作的 URL 路径由 pattern 和 extraPatterns 共同决定,不是拼接出来的
比如你配置了 'pattern' => 'users' 和 'extraPatterns' => ['POST activate' => 'activate'],那最终可访问的是 POST /users/activate,不是 /users/123/activate。要支持带 ID 的自定义动作,pattern 必须显式包含参数占位符。
- 想匹配
POST /users/123/activate:pattern 得写成'pattern' => 'users/<id:>'</id:>,extraPatterns 键仍为'POST activate' - 想同时支持无 ID 和带 ID 的同一动作?不行 —— Yii2 不允许一个
UrlRule同时覆盖两种结构;得拆成两条规则,或改用'tokens' => ['{id}' => '<id:>']</id:>配合更灵活的 pattern - 注意
tokens中的{id}必须和 pattern 中出现的占位符一致,否则参数不会注入到 action 参数里
控制器里接收额外参数时,别依赖 $_GET 或 $_POST,要用 action 方法签名
Yii2 的 RESTful 路由会把 pattern 中的 token(如 <id:></id:>)和 query string 自动绑定到 action 方法参数,前提是方法签名明确声明。如果只写 public function actionActivate(),那 /users/123/activate?format=csv 里的 format 就拿不到,$id 也为空。
- 正确写法:
public function actionActivate($id, $format = 'json') { ... },其中$id来自 URL 路径,$format来自 query string - 如果参数名和 token 名不一致(比如 token 是
<uid:></uid:>),就得用@param注解或在UrlRule里配'params' => ['id' => 'uid'] - body 提交的 JSON 数据不会自动绑定,仍需手动调用
Yii::$app->request->getBodyParams()或用Model::load()
最常被忽略的一点:extraPatterns 生效的前提是整个 UrlRule 的 controller 配置指向了正确的控制器类,且该控制器继承自 yii\rest\ActiveController(或至少实现了 actions() 方法返回含 class 的配置)。否则即使 URL 匹配成功,也会因找不到对应 action 而抛出 Invalid Route 错误。









