CodeIgniter 3如何通过路由实现站点多语言URL适配 规避SEO降权问题
解决方案
1. 修正路由规则
你之前的路由正则匹配范围不足,且未放在路由配置的最顶端导致解析优先级过低。打开/application/config/routes.php,将以下两条规则放在所有路由规则的最前面:
// 匹配带语言前缀的所有路径 $route['(en|id)/(:any)'] = '$2'; // 适配首页场景,首页控制器可根据你的实际业务调整 $route['(en|id)'] = 'home/index';
2. 调整语言获取逻辑
现在语言标识放在URL路径第一段,不再通过GET参数传递,删除原控制器方法中$_GET['lang']相关代码,改为通过URI类获取语言值。
推荐在公共控制器(如MY_Controller)的构造方法中统一处理语言逻辑,避免每个方法重复写:
public function __construct() { parent::__construct(); // 获取URL第一段作为语言标识 $lang = $this->uri->segment(1); // 仅保留合法语言值,避免恶意参数 if (in_array($lang, ['en', 'id'])) { $this->session->set_userdata('language', $lang); // 可在此处加载对应语言包 $this->lang->load('common', $lang); } }
3. 优化URL生成(可选)
为了避免后续手动拼接语言前缀出错,可重写CI原生的site_url方法,自动给生成的链接加上当前语言前缀。
在/application/helpers/目录下新建MY_url_helper.php:
function site_url($uri = '', $protocol = NULL) { $CI =& get_instance(); $lang = $CI->session->userdata('language'); // 无语言会话时使用默认语言 if (empty($lang)) { $lang = 'id'; } $uri = $lang . '/' . ltrim($uri, '/'); return $CI->config->site_url($uri, $protocol); }
后续调用site_url('culinary/detail/123-foo')就会自动生成带对应语言前缀的链接。
4. 无语言前缀访问适配(可选,SEO友好)
如果需要处理用户直接访问无语言前缀的URL的场景,可通过钩子实现301重定向到带前缀的路径,避免出现重复内容影响SEO:
- 打开
/application/config/config.php,开启钩子配置:
$config['enable_hooks'] = TRUE;
- 在
/application/hooks/目录下新建LangHook.php:
class LangHook { public function checkLangPrefix() { $CI =& get_instance(); $first_segment = $CI->uri->segment(1); $uri = $CI->uri->uri_string(); // 路径首段不是合法语言时,重定向到带默认语言的路径 if (!in_array($first_segment, ['en', 'id'])) { redirect('id/' . $uri, 'location', 301); } } }
- 打开
/application/config/hooks.php,注册钩子:
$hook['pre_controller'] = array( 'class' => 'LangHook', 'function' => 'checkLangPrefix', 'filename' => 'LangHook.php', 'filepath' => 'hooks' );
内容的提问来源于stack exchange,提问作者dapidmini
相关产品推荐
相关产品推荐

