CodeIgniter点击切换按钮切换数据库后刷新恢复默认的问题咨询
解决CodeIgniter切换数据库后刷新恢复默认的问题
这个问题我之前帮不少开发者踩过坑——核心原因就是你切换数据库的状态没有持久化,每次刷新页面都是一个全新的HTTP请求,之前临时切换的数据库配置自然就重置回默认值了。下面给你两个实用的解决方案,都是CodeIgniter生态里常用的:
方案一:用Session持久化切换状态(推荐,会话内有效)
这是最常用的方式,适合只需要在用户当前会话内保持数据库切换状态的场景:
先确保Session配置正常
检查application/config/config.php里的Session驱动设置,比如:$config['sess_driver'] = 'files'; // 或者database,根据你的配置来 $config['sess_save_path'] = APPPATH . 'sessions/'; $config['sess_expiration'] = 7200;确保Session能正常读写。
处理切换按钮的请求
写一个控制器方法来接收切换按钮的提交,把选中的数据库标识存在Session里:class DbSwitcher extends CI_Controller { public function toggle() { // 获取前端传过来的目标数据库标识(比如db1、db2) $targetDb = $this->input->post('db_target'); // 先验证这个数据库配置是否存在,防止非法输入 $allDbConfigs = $this->config->item('databases'); // 对应你配置文件里的数据库数组 if (isset($allDbConfigs[$targetDb])) { // 把选中的数据库标识存入Session $this->session->set_userdata('active_database', $targetDb); } // 跳回之前的页面 redirect($_SERVER['HTTP_REFERER']); } }自动加载并切换数据库
最好创建一个基础控制器MY_Controller.php放在application/core目录下,所有业务控制器都继承它,这样不用每个控制器都写重复代码:class MY_Controller extends CI_Controller { public function __construct() { parent::__construct(); // 从Session读取用户选中的数据库 $activeDb = $this->session->userdata('active_database'); if ($activeDb) { // 加载指定数据库,第二个参数TRUE表示返回数据库实例,替换默认的$this->db $this->db = $this->load->database($activeDb, TRUE); // 如果你的模型需要用这个数据库,这样替换后模型会自动使用新的连接 } } }要是你没有基础控制器,也可以把这段逻辑加到每个需要切换数据库的控制器的
__construct方法里。
方案二:用Cookie持久化(跨会话有效)
如果希望用户关闭浏览器再打开后,依然保持之前切换的数据库状态,就用Cookie:
切换时存入Cookie
修改刚才的toggle方法,把标识存在Cookie里:public function toggle() { $targetDb = $this->input->post('db_target'); $allDbConfigs = $this->config->item('databases'); if (isset($allDbConfigs[$targetDb])) { // 设置Cookie,有效期设为7天(可根据需求调整) $this->input->set_cookie('active_database', $targetDb, 3600 * 24 * 7); } redirect($_SERVER['HTTP_REFERER']); }初始化时读取Cookie
同样在基础控制器里添加逻辑:public function __construct() { parent::__construct(); $activeDb = $this->input->cookie('active_database'); // 验证数据库配置是否存在,避免无效Cookie if ($activeDb && isset($this->config->item('databases')[$activeDb])) { $this->db = $this->load->database($activeDb, TRUE); } }
注意事项
- 一定要做合法性验证:不能直接使用用户传入的数据库标识,必须检查它是否存在于你的配置数组中,防止恶意请求。
- 模型的数据库连接:如果你的模型是直接使用默认的
$this->db,那替换$this->db实例后,模型会自动使用新的数据库;如果模型是单独加载数据库的,需要调整模型里的加载逻辑。 - 测试时注意缓存:测试前可以清空浏览器的Session/Cookie,或者用隐私模式测试,避免旧数据干扰。
内容的提问来源于stack exchange,提问作者suchiSaa




