codeigniter 4 的 url_to() 函数仅识别显式命名的路由,必须通过 name() 方法注册路由名(如 $routes->get('/contact', 'contact::index')->name('contact')),否则模板调用会报错“route named 'contact' not found”。

命名路由必须用 name() 显式声明
CodeIgniter 4 的 url_to() 函数(用于模板中生成链接)只认「命名路由」,不认普通路由定义。如果你只写了 $routes->get('/contact', 'Contact::index');,模板里写 = url_to('contact') ?> 会报错:「Route named "contact" not found」。
正确做法是在路由注册时链式调用 name():
$routes->get('/contact', 'Contact::index')->name('contact');$routes->get('/user/(:num)', 'User::view/$1')->name('user.view');- 命名建议用英文点号分隔,比如
admin.dashboard、api.v1.users.index,便于语义管理和避免冲突
模板中用 url_to() 传参要严格匹配占位符顺序
命名路由的参数注入不是靠键名,而是靠位置。比如你定义了:$routes->get('/post/(:any)/(:num)', 'Post::show/$1/$2')->name('post.show');,那么在视图中必须按顺序传参:
- ✅ 正确:
= url_to('post.show', 'hello-world', 123) ?>→ 生成/post/hello-world/123 - ❌ 错误:
= url_to('post.show', ['slug' => 'hello-world', 'id' => 123]) ?>→ 会把整个数组当第一个参数,导致 URL 错乱 - 如果某个占位符是可选的(比如
/post/(:any)/(:num)?),CI4 不支持在url_to()中跳过中间参数;要么补默认值,要么另起一个命名路由
别把命名和控制器方法名搞混
路由名只是个字符串标识,和控制器类名、方法名完全无关。你可以给 Home::dashboard() 起名 app.home,也可以起名 main,只要不重复、不包含空格或特殊字符就行。
常见误区:
- 以为
url_to('Contact::index')能自动解析 —— 不行,必须提前用name()注册过才行 - 在多个环境(dev/staging/prod)中用了不同 base_url 却忘了
url_to()生成的是相对路径 —— 它默认不带域名,需配合site_url()或手动拼接 - 重命名路由后没清缓存,模板仍用旧名 —— CI4 路由编译后会缓存,改完 routes.php 记得删
writable/cache/routes/下文件或运行php spark cache:clear
带查询参数的链接不能靠 url_to() 自动加
url_to() 只处理路径段(path segment),不处理 query string。比如你想生成 /search?q=php&sort=date,不能写 url_to('search', 'php', 'date')。
正确方式是先用 url_to() 拿基础路径,再手动拼接:
<?php $url = url_to('search');
echo $url . '?q=' . urlencode($q) . '&sort=' . urlencode($sort);
?>
或者封装成辅助函数,避免模板里重复写逻辑。这点容易被忽略,尤其在搜索、分页等场景下,直接拼错 URL 编码会导致中文乱码或 400 错误。











