访问HTML页面时EventSubscriberInterface不生效是什么原因?
问题根因
你遇到的是静态资源默认不走PHP框架处理的典型问题:Nginx/Apache等Web服务器的默认配置会直接匹配到.html这类静态文件,无需经过Symfony内核(也就是不会走到public/index.php入口),所以你注册的KernelRequest事件订阅器完全不会被触发,自然构造函数里的die也不会执行。
可行解决方案
方案1:调整Web服务器配置(最直接)
修改你的Web服务配置,让/modules路径下的所有请求都转发给Symfony入口处理,不直接返回静态文件:
- 如果你用Nginx,需要在静态资源匹配规则之前加如下配置,优先级要高于普通静态文件匹配:
location ^~ /modules/ { try_files $uri /index.php$is_args$args; }
- 如果你用Apache,在
public/modules目录下新增.htaccess文件,内容如下:
RewriteEngine On RewriteCond %{REQUEST_FILENAME} -f RewriteRule ^(.*)$ /index.php [QSA,L]
方案2:迁移静态文件到非公开目录(更安全)
把modules目录从public下移到项目根目录的data之类的非公开目录,新增一个专门的控制器负责读取对应HTML文件内容返回,同时在控制器或者事件订阅器里做权限校验,这种方案不需要修改服务器配置,也避免了静态文件意外泄露的风险。
现有代码优化建议
- 不要直接读取
$_SESSION['_sf2_attributes']内置键值,改用Symfony官方提供的Security服务获取当前登录用户信息,兼容性更强 - 现有SQL存在严重的SQL注入风险,不要直接拼接变量到SQL语句中,改用参数绑定的方式传参:
// 优化后的查询逻辑 $statement = $connection->prepare("SELECT * FROM eurotest_users eu LEFT JOIN user_range ur On eu.id = ur.user_id LEFT JOIN user_version uv On eu.id = uv.user_id LEFT JOIN eurotest_module em On ur.range_id = em.module_range_id AND uv.version_id = em.module_version_id where eu.email = :email and em.folder= :folder"); $statement->execute([ 'email' => $_SESSION['_sf2_attributes']['_security.last_username'], 'folder' => $RequestUri ]);
- 注意URI判断逻辑:如果你的项目根目录已经指向
public,实际请求的URI应该是/modules/story.html,不会携带/public前缀,建议先打印$RequestUri确认实际值,避免匹配规则失效。
内容的提问来源于stack exchange,提问作者Ahmed guesmi
相关产品推荐
相关产品推荐

