在学习《PHP网站开发实例教程(第2版)》的第2.3.3小节时,发现按作者原代码始终无法实现隐藏入口文件功能。怀疑过各种原因,包括小皮面板环境可能与作者配置的WAMP环境不同、配置不同或者php、apache版本差异等等,经过近一天的尝试才终于解决问题。
一、核心问题描述
为实现隐藏URL中的“/index.php”字段,书中Apache分布式配置文件“.htaccess”中,代码如下:
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>
获取当前URL地址的代码如下:
$pathinfo = $_SERVER['PATH_INFO'];
正常访问地址://myframe.test/index.php/student
隐藏访问地址://myframe.test/student
在上述条件下,隐藏“/index.php”后URL访问结果始终是“No input file specified”。
这并非是Apache主机配置问题,因为已确认开启主配置文件httpd.conf中Rewrite功能模块,并在该文件以及虚拟主机配置文件中,设置了“AllowOverride All”。另外提到,需在此处同时添加语句“AcceptPathInfo On”以启用Apache能读取PATH_INFO功能,配置如下。经验证仍然无法解决问题。
<Directory "D:/phpstudy_pro/WWW/myframe/public">
Options FollowSymLinks ExecCGI
AllowOverride All
Order allow,deny
Allow from all
Require all granted
AcceptPathInfo On
DirectoryIndex index.php index.html error/index.html
</Directory>
<Files *.php>
AcceptPathInfo On
</Files>
部分观点认为,应检查php.ini配置,打开“cgi.fix_pathinfo=1”,确保php能通过PATH_INFO传递变量。经验证也无法解决问题,错误提示“No input file specified”本身也说明应该与Apache服务器相关。
二、解决方案探索
经过各种尝试,除非使用带有“index.php”字段的正常访问url,否则一律报错。
1、.htaccess分布式配置文件是否没有起作用。如删除配置文件运行隐藏访问地址,页面结果直接显示“404 Not Found”,并不是“No input file specified”。说明分布式配置文件在起作用。
2、修改分布式配置文件的RewriteRule如下(index.php后面加入?):
RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
此时程序可运行,但是新问题是:使用隐藏访问地址无法请求到想要的结果,如下代码返回结果为空字符串。
$pathinfo = $_SERVER['PATH_INFO'];
var_dump($pathinfo);
经了解,重写URL规则中index.php后面是否添加"?"只是影响地址获取时是否保留?后面的部分,而访问地址中并没有“?”部分。为什么重写规则的“?”区别会导致Apache服务器完全不同的行为,该处留下了疑惑。
3、经过反复尝试发现,使用“REQUEST_URI”或“QUERY_STRING”代替“PATH_INFO”,程序可正常运行并返回正确结果。如下代码均可正常获取到隐藏URL的后面部分“/student”。
$pathinfo = $_SERVER['REQUEST_URI'];
$pathinfo = $_SERVER['QUERY_STRING'];
经了解学习到以下内容,但是对于本案例,仍然没太理解这3个客户端数据的区别,此处存疑。
PATH_INFO:包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息,如果存在的话。
QUERY_STRING:请求页面查询(query)的字符串,URL中第一个问号?之后的内容。
REQUEST_URI:访问此页面所需的URL,包含QUERY_STRING部分。
好在隐藏入口文件功能已经实现,只是未知其所以然。

1275

被折叠的 条评论
为什么被折叠?



