如何在Laravel中为外部文件夹配置子域名路由?
需求可行性及实现方法
嘿,这个需求完全可以实现,但你之前用相对路径../的方式搞错了Laravel路由的逻辑——Laravel路由是基于HTTP请求的URL路径,不是服务器文件系统的相对路径,所以这种写法根本行不通。下面给你拆解具体的实现步骤:
第一步:调整服务器配置(关键前提)
首先得确保subdomain.mysite.com的请求能被Laravel主应用处理,而不是直接指向服务器上的subdomain文件夹。这里以常用的Nginx为例,给你两种场景的配置参考:
场景1:子域名所有请求都走Laravel路由
如果希望subdomain.mysite.com下的所有请求都由Laravel接管,把Nginx配置改成这样:
server { listen 80; server_name subdomain.mysite.com; # 指向主Laravel应用的public目录 root /path/to/your/server/mysite.com/myapp/public; index index.php; location / { try_files $uri $uri/ /index.php?$query_string; } # PHP处理配置(和主域名的配置保持一致) location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; # 换成你的PHP-FPM路径 fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } }
场景2:保留原subdomain文件夹的静态文件,仅动态请求走Laravel
如果还想让subdomain.mysite.com下的静态文件(比如图片、HTML)直接从原subdomain文件夹读取,只有像/abc/def这类动态请求走Laravel,可以这么配置:
server { listen 80; server_name subdomain.mysite.com; # 先设置静态文件根目录为原subdomain文件夹 root /path/to/your/server/mysite.com/subdomain; index index.php index.html; # 优先检查静态文件是否存在,存在则直接返回 location / { try_files $uri $uri/ @laravel; } # 静态文件不存在时,转发请求到Laravel主应用 location @laravel { root /path/to/your/server/mysite.com/myapp/public; fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root/index.php; fastcgi_param QUERY_STRING $query_string; include fastcgi_params; } # 处理subdomain文件夹内的PHP文件(如果有的话) location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } }
如果用Apache的话,修改虚拟主机配置,让subdomain.mysite.com指向Laravel的public目录,同时确保mod_rewrite模块开启,public/.htaccess配置正常。
第二步:Laravel路由配置
搞定服务器配置后,就可以在Laravel里用子域名路由分组来定义subdomain.mysite.com下的路由了,完全不需要用相对路径:
// 主应用的路由(对应mysite.com/myapp/something),保持你原来的写法就行 Route::get('something', ['uses' => 'someController@index']); // 子域名专属路由分组 Route::domain('subdomain.mysite.com')->group(function () { // 对应subdomain.mysite.com/abc/def的请求,$someVariable会匹配def Route::get('abc/{someVariable}', ['uses' => 'someController@someFunction']); // 你还可以在这里添加更多子域名下的路由,比如: // Route::post('submit-form', ['uses' => 'SubdomainController@handleSubmit']); });
如果你的Laravel版本是8.x及以上,推荐用更现代的控制器写法:
use App\Http\Controllers\SomeController; Route::domain('subdomain.mysite.com')->group(function () { Route::get('abc/{someVariable}', [SomeController::class, 'someFunction']); });
注意事项
- 确保你的DNS配置已经把
subdomain.mysite.com指向了服务器的IP地址,否则子域名根本访问不了。 - 测试前记得清空Laravel的路由缓存(执行
php artisan route:clear),避免旧路由配置干扰。 - 如果子域名需要支持HTTPS,记得在服务器配置里添加SSL证书相关的配置(比如
listen 443 ssl等)。
内容的提问来源于stack exchange,提问作者Abraham Romero
相关产品推荐
相关产品推荐

