如何在同域名下将CodeIgniter项目作为Laravel子目录运行?
我明白你现在的困境——把Laravel放在主域名domain.com,CodeIgniter放在子目录domain.com/design,还要共享Session,之前折腾了Apache配置和.htaccess都没搞定,甚至把文件都删了。别着急,咱们一步步来把这个问题解决掉:
第一步:恢复并配置Apache VirtualHost
首先得把Apache的虚拟主机配置好,这是基础。找到你的Apache配置目录(通常是/etc/apache2/sites-available/),创建或编辑对应域名的配置文件(比如domain.com.conf),添加以下内容:
<VirtualHost *:80> ServerName domain.com ServerAlias www.domain.com # Laravel项目的根目录指向public文件夹 DocumentRoot /path/to/laravel/public # 配置CodeIgniter子目录的别名,指向CI项目的入口目录(通常是CI的public或根目录) Alias /design /path/to/codeigniter/public # 给Laravel主目录设置权限 <Directory /path/to/laravel/public> Options Indexes FollowSymLinks MultiViews AllowOverride All Require all granted </Directory> # 给CodeIgniter子目录设置权限 <Directory /path/to/codeigniter/public> Options Indexes FollowSymLinks MultiViews AllowOverride All Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/domain.com-error.log CustomLog ${APACHE_LOG_DIR}/domain.com-access.log combined </VirtualHost>
配置完后,启用这个站点并重启Apache:
sudo a2ensite domain.com.conf sudo systemctl restart apache2
第二步:统一两个框架的Session核心配置
Session共享的关键是让两个框架的Cookie参数完全一致,这样浏览器才会把同一个Session Cookie发送给两个项目。
Laravel端配置(.env文件)
打开Laravel根目录的.env文件,修改以下Session相关参数:
SESSION_DOMAIN=.domain.com # 前面的点表示包含所有子域名/子目录 SESSION_PATH=/ # 根路径,确保Cookie在整个域名下有效 SESSION_DRIVER=database # 推荐用数据库驱动,比file驱动更稳定易共享 SESSION_COOKIE_NAME=shared_session # 自定义一个统一的Cookie名称,和CI保持一致
如果用数据库驱动,记得先运行Laravel的Session迁移生成表:
php artisan session:table php artisan migrate
CodeIgniter端配置(application/config/config.php)
打开CI的配置文件,修改Session相关配置,和Laravel的参数对齐:
// 统一Cookie名称 $config['sess_cookie_name'] = 'shared_session'; // 同域名,注意前面的点 $config['sess_cookie_domain'] = '.domain.com'; // 根路径 $config['sess_cookie_path'] = '/'; // 驱动和Laravel保持一致,如果用数据库的话 $config['sess_driver'] = 'database'; // 数据库表名要和Laravel的sessions表一致(或者调整Laravel的表名匹配CI的ci_sessions) $config['sess_save_path'] = 'sessions'; // 其他参数保持一致,比如httponly、secure等 $config['sess_httponly'] = true; $config['sess_secure'] = false; // 如果用HTTPS就设为true
如果CI用数据库驱动,要确保CI的数据库配置和Laravel连接的是同一个数据库,并且能读写sessions表(如果Laravel用的是默认表名)。
第三步:配置.htaccess避免路由冲突
两个框架的.htaccess要配合工作,确保主域名的请求交给Laravel,/design开头的请求交给CodeIgniter。
Laravel根目录的.htaccess(public/.htaccess)
修改Laravel的.htaccess,在RewriteRule之前添加一条规则,排除/design路径的请求:
<IfModule mod_rewrite.c> <IfModule mod_negotiation.c> Options -MultiViews -Indexes </IfModule> RewriteEngine On # 新增:排除/design路径,交给CI处理 RewriteCond %{REQUEST_URI} !^/design # 处理Laravel的路由 RewriteRule ^(.*)$ index.php/$1 [L] </IfModule>
CodeIgniter子目录的.htaccess(/design/.htaccess)
在CI的入口目录(对应Apache Alias的/path/to/codeigniter/public)创建或编辑.htaccess,添加CI的标准路由规则:
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase /design/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php/$1 [L] </IfModule>
第四步:测试与排查
配置完成后,重启Apache,然后做以下测试:
- 访问
domain.com,在Laravel中设置一个Session值,比如session(['test' => 'hello from laravel']) - 访问
domain.com/design,在CI中尝试读取这个Session值,比如echo $this->session->userdata('test'); - 反过来在CI中设置Session,看Laravel能否读取
如果还是有问题,用浏览器开发者工具(F12)查看Application标签下的Cookies,确认:
- Cookie的Domain是
.domain.com - Path是
/ - Cookie名称和你配置的一致
另外检查权限:如果用file驱动,Session目录的权限要让Apache用户(比如www-data)能读写;如果用数据库驱动,确保两个框架的数据库用户有对应的读写权限。
内容的提问来源于stack exchange,提问作者Azhar

