Symfony 6移除URL中/public/路径的正确配置方法求助
我使用Symfony 6框架,已安装Apache Pack,执行recipes:update后无变化,确认Apache Pack已更新且生成了.htaccess文件,但网站仍需通过mydomain.com/public/访问。我希望移除URL中的public路径,目前部署在Cloudways平台,无法修改目录结构(避免破坏Git自动部署流程)。我曾实现过该需求,但想找到官方认可的正确配置方式,而非临时可行的规则。查阅Symfony文档未找到相关说明,同时疑惑Apache Pack为何未处理该配置,是否安装过程存在问题?
当前已有的.htaccess配置
/public目录下的.htaccess
# Use the front controller as index file. It serves as a fallback solution when # every other rewrite/redirect fails (e.g. in an aliased environment without # mod_rewrite). Additionally, this reduces the matching process for the # start page (path "/") because otherwise Apache will apply the rewriting rules # to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl). DirectoryIndex index.php # By default, Apache does not evaluate symbolic links if you did not enable this # feature in your server configuration. Uncomment the following line if you # install assets as symlinks or if you experience problems related to symlinks # when compiling LESS/Sass/CoffeScript assets. # Options +FollowSymlinks # Disabling MultiViews prevents unwanted negotiation, e.g. "/index" should not resolve # to the front controller "/index.php" but be rewritten to "/index.php/index". <IfModule mod_negotiation.c> Options -MultiViews </IfModule> <IfModule mod_rewrite.c> RewriteEngine On # Determine the RewriteBase automatically and set it as environment variable. # If you are using Apache aliases to do mass virtual hosting or installed the # project in a subdirectory, the base path will be prepended to allow proper # resolution of the index.php file and to redirect to the correct URI. It will # work in environments without path prefix as well, providing a safe, one-size # fits all solution. But as you do not need it in this case, you can comment # the following 2 lines to eliminate the overhead. RewriteCond %{REQUEST_URI}::$0 ^(/.+)/(.*)::\2$ RewriteRule .* - [E=BASE:%1] # Sets the HTTP_AUTHORIZATION header removed by Apache RewriteCond %{HTTP:Authorization} .+ RewriteRule ^ - [E=HTTP_AUTHORIZATION:%0] # Redirect to URI without front controller to prevent duplicate content # (with and without `/index.php`). Only do this redirect on the initial # rewrite by Apache and not on subsequent cycles. Otherwise we would get an # endless redirect loop (request -> rewrite to front controller -> # redirect -> request -> ...). # So in case you get a "too many redirects" error or you always get redirected # to the start page because your Apache does not expose the REDIRECT_STATUS # environment variable, you have 2 choices: # - disable this feature by commenting the following 2 lines or # - use Apache >= 2.3.9 and replace all L flags by END flags and remove the # following RewriteCond (best solution) RewriteCond %{ENV:REDIRECT_STATUS} ="" RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L] # If the requested filename exists, simply serve it. # We only want to let Apache serve files and not directories. # Rewrite all other queries to the front controller. RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ %{ENV:BASE}/index.php [L] </IfModule> <IfModule !mod_rewrite.c> <IfModule mod_alias.c> # When mod_rewrite is not available, we instruct a temporary redirect of # the start page to the front controller explicitly so that the website # and the generated links can still be used. RedirectMatch 307 ^/$ /index.php/ # RedirectTemp cannot be used instead </IfModule> </IfModule>
根目录(Cloudways的public_html)下的.htaccess
RewriteEngine On RewriteBase / RewriteCond %{REQUEST_URI} !^/public/ RewriteRule ^(.*)$ public/$1
官方认可的配置方案
在Cloudways这种无法修改Web根目录指向public的场景下,Symfony官方推荐的正确做法是替换根目录的.htaccess规则,确保请求被正确转发到public目录,同时避免循环重定向,且兼容Symfony内置的路由规则。
替换后的根目录.htaccess内容
RewriteEngine On RewriteBase / # 实际存在的文件或目录直接返回,不转发到public RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] # 所有其他请求转发到public目录对应的路径 RewriteRule ^(.*)$ public/$1 [L]
为什么这是官方认可的?
这个规则完全符合Symfony对Web服务器配置的核心要求:
- 优先返回静态资源(比如根目录的
robots.txt、favicon.ico),避免不必要的转发 - 确保所有动态请求都通过Symfony的前端控制器(
public/index.php)处理 - 避免循环重定向问题(原规则未判断实际文件/目录,可能导致
public下的资源被重复转发)
关于Apache Pack未自动配置的说明
Apache Pack的核心职责是生成public目录内的.htaccess规则,用于处理Symfony应用内部的路由重写(比如将请求转发到index.php)。它并不负责配置Web服务器的根目录转发规则——因为这属于服务器级别的配置,不同托管平台(如Cloudways、cPanel)的目录结构和权限限制差异极大,Symfony官方无法提供通用的自动配置逻辑。
所以你的Apache Pack安装过程没有问题,它已经完成了它的设计职责:生成public目录下的标准Symfony重写规则。
内容的提问来源于stack exchange,提问作者Matt Welander

