You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony 6移除URL中/public/路径的正确配置方法求助

移除Symfony 6 URL中的public路径(Cloudways部署场景)

我使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 09:09:57