伪静态可以隐藏后端实现原理,便于搜索引擎收藏,开起来高大上一些。
通过nginx路径重写跳转到后端,再分发到控制器。
为了简单,以nginx
和php-fpm
的方式部署项目,网站根目录就两个文件:
helpers.php
,其中存放各种函数
index.php
,用于提取路由并分发到函数中
适合功能非常简单,没必要使用框架的情况。
第一步:配置nginx
location / { try_files $uri $uri/ /index.php?$query_string; }
这个路径的优先级是最低的,先查找文件和目录,如果都没有以index.php
文件和url参数在内部重定向到fastcgi
第二步:提取路由信息
伪静态url中没有文件,只是路由信息,例如:http://localhost/article/top?p=3
因为是内部重定向,nginx收到的$request_uri
还是/article/top?p=3
,fastcgi收到的REQUEST_URI
也是该值,而SCRIPT_NAME
则为index.php
。
通过以下函数可以得到pathInfo
,应该为/article/top
function getPathInfo(){ $requestUri = $_SERVER['REQUEST_URI']; $pos = strpos($requestUri, '?'); if($pos !== false){ $requestUri = substr($requestUri, 0, $pos); } if ('' !== $requestUri && '/' !== $requestUri[0]) { $requestUri = '/'.$requestUri; } if (false === $requestUri || '' === $requestUri) { return '/'; } return (string) $requestUri; }
第三步:分发到控制器
因为是极简实现,仅分发到具体的函数即可。
上面的路由信息被分发到函数article_top
,在该函数中实现具体的逻辑即可。
如果没有匹配的路由就返回nginx默认的404,这样不会暴露后端信息,如果php.ini
中关闭expose_php
则前端没有任何PHP相关的信息。
require_once 'helpers.php'; $route = substr(getPathInfo(), 1); if(in_array($route, ['article/top'])){ $method = str_replace('/', '_', $route); $method(); }else{ http_response_code(404); echo '<html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx</center> </body> </html>'; }
框架和这类似,只不过使用了composer,功能更加丰富。
symfony/http-foundation
中有根据REQUEST_URI
提取PathInfo相关的代码,只不过,考虑到了baseurl,就是将框架放在一个目录中的情况。
use Symfony\Component\HttpFoundation\Request; $request = Request::createFromGlobals(); $request->getPathInfo();
因为使用了composer,则需要将index.php放到public目录中,App中放置Controller、Model等PHP类,前端页面放到模板中,路由放到routes目录中。这样方便收集路由,并分发到Controller子类的具体方法。
网站的根目录需要是public,就是代码的一个子目录。