CodeIgniter 的 _remap() 是控制器級的「萬能路由攔截器」,允許完全自定義 URI 到方法的映射關係。本文解析其機制,並展示「隱藏真實方法名」與「方法級權限控制」兩大經典應用場景。
public function _remap($method, $params = []) 後,**所有**對該控制器的請求均進入此方法。$method 參數傳入,後續段作為 $params 陣列。_remap() 內手動分發。需求:將 /blog/say 對外呈現為 /blog/hello,內部仍調用 say()。
class Blog extends CI_Controller {
public function _remap($method, $params = []) {
// 映射表:外部名 => 內部方法
$map = [
'hello' => 'say',
'list' => 'index',
'view' => 'detail',
];
$internalMethod = $map[$method] ?? $method; // 無映射則直接用原名
if (method_exists($this, $internalMethod)) {
return call_user_func_array([$this, $internalMethod], $params);
}
show_404(); // 方法不存在
}
public function say($name = 'World') {
echo "Hello, $name!";
}
// 原本的 say() 現在無法直接通過 /blog/say 訪問
}
效果:
/blog/hello/John → 顯示 "Hello, John!"/blog/say/John → 404(被隱藏)class Admin extends CI_Controller {
public function _remap($method, $params = []) {
// 1. 公開方法白名單(無需登入)
$public = ['login', 'captcha', 'forgot_password'];
if (in_array($method, $public, true)) {
return $this->$method(...$params);
}
// 2. 檢查登入
if (empty($this->session->userdata('admin_id'))) {
return $this->login(); // 或 redirect('admin/login')
}
// 3. 權限檢查:角色 -> 允許方法列表
$role = $this->session->userdata('role'); // 'super', 'editor', 'viewer'
$acl = [
'super' => ['*'], // 所有權限
'editor' => ['article_*', 'category_*', 'media_*'],
'viewer' => ['article_view', 'dashboard'],
];
$allowed = $acl[$role] ?? [];
$hasAccess = false;
foreach ($allowed as $pattern) {
if ($pattern === '*' || fnmatch($pattern, $method)) {
$hasAccess = true;
break;
}
}
if ($hasAccess && method_exists($this, $method)) {
return $this->$method(...$params);
}
// 4. 無權限
show_error('權限不足:' . $method, 403);
}
public function article_list() { /* ... */ }
public function article_edit($id) { /* ... */ }
public function article_view($id) { /* ... */ }
public function user_manage() { /* ... */ }
// ...
}
_remap 末尾 `return call_user_func_array([$this, $method], $params);` 維持原有映射。$params 為數值索引陣列,需用 `...` 解包傳遞(PHP 5.6+)。_remap 每請求執行一次,邏輯勿過重;權限檢查建議快取 ACL 規則。_remap,注意優先級。_remap 不影響此機制。_remap() 是 CodeIgniter 靈活路由的核心擴展點。**適度使用**可實現 URL 語義化、內部結構隱藏、集中式權限控制。但過度濫用會導致控制器邏輯膨脹、難以追蹤,建議:簡單映射用 routes.php,複雜權限/別名用 _remap,核心業務邏輯保持在具體方法中。