1

PHP pathinfo 和 url重写

 2 years ago
source link: http://hustnaive.github.io/php/2015/07/30/php-pathinfo-urlrewrite.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

PHP pathinfo 和 url重写


假设我们的web服务器部署在192.168.59.103:8080,服务器操作系统为ubuntu14.04,php版本为php5.5.9,web服务器为apache,以apache2ctl -D 'FOREGROUND'模式运行。

我们的目录结构如下:

php-mvc/
    |- index.php
        |- test/
            |- index.php

其中/index.php和test/index.php里面的代码一样,都为:

<?php

print_r($_SERVER);

即,输出$_SERVER环境变量的内容,这个变量存储与服务器有关的环境配置信息。

这里,我们需要关注php里面的一个叫PATH_INFO的环境变量,那么PATH_INFO是什么呢?回答这个问题之前,我们先看几个例子:

访问index.php

http://192.168.59.103:8080/index.php/a/b/c?d=e&f=g

Array
(
    ...

    [SERVER_SOFTWARE] => Apache/2.4.7 (Ubuntu)
    [SERVER_NAME] => 192.168.59.103
    [SERVER_ADDR] => 172.17.0.22
    [SERVER_PORT] => 8080
    [REMOTE_ADDR] => 192.168.59.3
    [DOCUMENT_ROOT] => /var/www/html
    [REQUEST_SCHEME] => http
    [CONTEXT_PREFIX] => 
    [CONTEXT_DOCUMENT_ROOT] => /var/www/html
    [SERVER_ADMIN] => webmaster@localhost
    [SCRIPT_FILENAME] => /var/www/html/index.php
    [REMOTE_PORT] => 52652
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.1
    [REQUEST_METHOD] => GET
    [QUERY_STRING] => d=e&f=g
    [REQUEST_URI] => /index.php/a/b/c?d=e&f=g
    [SCRIPT_NAME] => /index.php
    [PATH_INFO] => /a/b/c
    [PATH_TRANSLATED] => /var/www/html/a/b/c
    [PHP_SELF] => /index.php/a/b/c
    [REQUEST_TIME_FLOAT] => 1436888490.582
    [REQUEST_TIME] => 1436888490
)

访问/test/index.php

http://192.168.59.103:8080/test/index.php/a/b/c?d=e&f=g

Array
(
    ...

    [SERVER_SOFTWARE] => Apache/2.4.7 (Ubuntu)
    [SERVER_NAME] => 192.168.59.103
    [SERVER_ADDR] => 172.17.0.22
    [SERVER_PORT] => 8080
    [REMOTE_ADDR] => 192.168.59.3
    [DOCUMENT_ROOT] => /var/www/html
    [REQUEST_SCHEME] => http
    [CONTEXT_PREFIX] => 
    [CONTEXT_DOCUMENT_ROOT] => /var/www/html
    [SERVER_ADMIN] => webmaster@localhost
    [SCRIPT_FILENAME] => /var/www/html/test/index.php
    [REMOTE_PORT] => 52651
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.1
    [REQUEST_METHOD] => GET
    [QUERY_STRING] => d=e&f=g
    [REQUEST_URI] => /test/index.php/a/b/c?d=e&f=g
    [SCRIPT_NAME] => /test/index.php
    [PATH_INFO] => /a/b/c
    [PATH_TRANSLATED] => /var/www/html/a/b/c
    [PHP_SELF] => /test/index.php/a/b/c
    [REQUEST_TIME_FLOAT] => 1436888285.586
    [REQUEST_TIME] => 1436888285
)

访问/(apache默认设置index为index.php)

http://192.168.59.103:8080/

Array
(
    ...

    [SERVER_SOFTWARE] => Apache/2.4.7 (Ubuntu)
    [SERVER_NAME] => 192.168.59.103
    [SERVER_ADDR] => 172.17.0.22
    [SERVER_PORT] => 8080
    [REMOTE_ADDR] => 192.168.59.3
    [DOCUMENT_ROOT] => /var/www/html
    [REQUEST_SCHEME] => http
    [CONTEXT_PREFIX] => 
    [CONTEXT_DOCUMENT_ROOT] => /var/www/html
    [SERVER_ADMIN] => webmaster@localhost
    [SCRIPT_FILENAME] => /var/www/html/index.php
    [REMOTE_PORT] => 52499
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.1
    [REQUEST_METHOD] => GET
    [QUERY_STRING] => 
    [REQUEST_URI] => /
    [SCRIPT_NAME] => /index.php
    [PHP_SELF] => /index.php
    [REQUEST_TIME_FLOAT] => 1436887771.889
    [REQUEST_TIME] => 1436887771
)

通过上面的示例,你应该知道pathinfo就是我们的请求脚本(xxx.php)在php文件后面的路径部分。pathinfo是cgi的标准环境变量,它用于服务器往cgi程序中传递路径信息。而我们知道,php一般是以CGI/FastCGI模式与WEB服务器协作的,所以$_SERVER[‘PATH_INFO’]里面存储着服务器遵循CGI标准传递过来的pathinfo信息。

有人可能会问,我这样大段落的讲pathinfo起什么作用呢?其实,目前大多数的成熟的PHP-MVC框架都是通过pathinfo与url重写来实现其URL路由的。我们经常可以看到浏览器输入的某个地址,但是这个地址缺并没有在我们的webroot目录下面,这都是pathinfo和url重写的功劳。

讲完了pathinfo,下面讲讲url重写是什么了。

URL重写

url重写是现代web服务器提供的一种特性,目前主流的nginx、apache、iis都支持url重写。 url重写可以将一个http访问请求内部重定向到另外一个位置。

简单说,我们可以建立一个path/to/a -> path/to/b的url重写规则,当我们浏览器访问path/to/a的时候,服务器会内部重定向到path/to/b,并返回b内容。

这个重写的具体语法不同的服务器有其具体的语法规定,大家可以参考相应的文档,这里不延伸。

那么,结合url重写和pathinfo,我们建立一个path/to/a -> index.php/path/to/a的url重写规则,这样,我们就可以在index.php中通过PATH_INFO获取到我们的请求url了,而这条规则则是目前大多数的PHP-MVC框架的核心支撑了。

框架会首先要求服务器配置支持url重写,并将请求重定向到框架的入口文件,然后,入口文件的主要职责就是解析pathinfo,并根据框架的约定来找到对应的代码文件,并执行相应的控制器代码。这样做的主要好处是可以隐藏我们请求URL中的index.php,达到URL美化的目的。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK