我正在为php应用程序制作工具包。我已经建立了一个基于某些约定的路由系统,它运行良好,但我想学习如何制作mod_rewrite规则或任何其他东西,以最终使网站看起来很好看,并且对seo有好处。
路由系统从设置app和url根目录的配置文件开始。
$app_root = $_SERVER["DOCUMENT_ROOT"].dirname($_SERVER["PHP_SELF"])."/";
$app_url = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/';
define("APP_URL",$app_url);
define("APP_ROOT",$app_root);
路由始终从index.php开始,它使得GET参数控制器的控制器@操作实例=?& action =?
这是index.php
<?php
include_once 'controller/Frontend.php';
require 'libraries/Router.php';
$params=array();
if(isset($_GET['controller'])&&isset($_GET['action'])){
$c = $_GET['controller'];
$a = $_GET['action'];
// add all query string additional params to method signature i.e. &id=x&category=y
$queryParams = array_keys($_GET);
$queryValues = array_values($_GET);
for ($i=2;$i<count($queryParams);$i++) {
$params[$queryParams[$i]] = $queryValues[$i];
}
if ($_POST) {
// add all query string additional params to method signature i.e. &id=x&category=y
$queryParams = array_keys($_POST);
$queryValues = array_values($_POST);
for ($i=0;$i<count($_POST);$i++) {
$params[$queryParams[$i]] = $queryValues[$i];
}
}
include_once APP_ROOT."/controller/$c.php";
$controller = new $c();
$controller->$a($params);
} else {
//attiva controller predefinito
$controller = new Frontend();
$controller->index();
}
这允许选择控制器和路由器必须调用的操作。
此处的路由器功能从根目录中的settings.php获取APP URL。你给我两个控制器@ action params作为字符串,它使URL如下: ?的index.php控制器= X&安培;行动= Y&安培; [参数...]
<?php
要求&#39; ./ settings.php&#39;;
function router($controller,$action,$query_data="") {
$param = is_array($query_data) ? http_build_query($query_data) : "$query_data";
$url = APP_URL."index.php?controller=$controller&action=$action&$param";
return $url;
}
function relativeRouter ($controller,$action,$query_data=""){
$param = is_array($query_data) ? http_build_query($query_data) : "$query_data";
$url = "index.php?controller=$controller&action=$action&$param";
return $url;
}
function redirectToOriginalUrl() {
$url = $_SERVER['HTTP_REQUEST_URI'];
header("location: $url");
}
function switchAction ($controller, $action) {
$r = router($controller, $action);
header("location:$r", true, 302);
}
在模板文件中,我调用路由器(&#39;控制器,&#39;操作&#39;)来检索网址的动作,并传递GET / POST数据(从index.php收集,放入&# 39;将它们作为数组进入方法签名。
不要责怪我使用全局POST / GET而不过滤我还在开发这个东西,安全事情将在之后制作;)
我想问一下,如果有人可以分享关于如何制作网站/页面/动作等漂亮网址的一些想法.... 例如www.site.com/blog/post?id=1
(实际上路由器函数中的N个参数($ query_data)以这种方式工作,你传递数组[&#39; id&#39; =&gt;&#39; 1&#39;]你会得到?id = 1)
制作好网址的最佳策略是什么? 非常感谢你,还在学习PHP。
如果有最好的方式来做这些事情,请提供反馈。
答案 0 :(得分:0)
我发现自己回答了这个问题,我在这里发帖也许它很有用。
我在根目录中添加了一个.htaccess文件:
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
这会将每个请求返回到root / index.php文件。
索引文件从HTTP请求中收集路由,检查路由是否存在于“routes.json”文件中。
URL以这种方式编写: site.com/controller/action。 GET参数编写如下 site.com/controller/action/[params] / [value] ......此输出例如site.com/blog/post/id/1 那对REST也应该没问题。
这里是index.php
<?php
require 'controller/Frontend.php';
require 'Class/Router.php';
//require 'libraries/Router.php';
/*
* ** ROUTING SETTINGS **
*/
$app_root = $_SERVER["DOCUMENT_ROOT"].dirname($_SERVER["PHP_SELF"])."/";
$app_url = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/';
define("APP_URL",$app_url);
define("APP_ROOT",$app_root);
$basepath = implode('/', array_slice(explode('/', $_SERVER['SCRIPT_NAME']), 0, -1));
$uri = substr($_SERVER['REQUEST_URI'], strlen($basepath));
//echo $uri;
if ($uri == "/") {
$frontend = new Frontend();
$frontend->index();
} else {
$root = ltrim ($uri, '/');
//$paths = explode("/", $uri);
$paths = parse_url($root, PHP_URL_PATH);
$route = explode("/",$paths);
$request = new \PlayPhp\Classes\Request();
// controller
$c = $route[0];
// action
$a = $route[1];
$reverse = Router::inverseRoute($c,$a);
$rest = $_SERVER['REQUEST_METHOD'];
switch ($rest) {
case 'PUT':
//rest_put($request);
break;
case 'POST':
if (Router::checkRoutes($reverse, "POST")) {
foreach ($_POST as $name => $value) {
$request->setPost($name,$value);
}
break;
} else {
Router::notFound($reverse,"POST");
}
case 'GET':
if (Router::checkRoutes($reverse, "GET")) {
for ($i = 2; $i < count($route); $i++) {
$request->setGet($route[$i], $route[++$i]);
}
break;
} else {
Router::notFound($reverse,"GET");
}
break;
case 'HEAD':
//rest_head($request);
break;
case 'DELETE':
//rest_delete($request);
break;
case 'OPTIONS':
//rest_options($request);
break;
default:
//rest_error($request);
break;
}
include_once APP_ROOT.'controller/'.$c.'.php';
$controller = new $c();
$controller->$a($request);
}
路由器类:
<?php
include 'config/app.php';
/*
* Copyright (C) 2015 yuri.blanc
*/
require 'Class/http/Request.php';
class Router {
protected static $routes;
private function __construct() {
Router::$routes = json_decode(file_get_contents(APP_ROOT.'config/routes.json'));
}
public static function getInstance(){
if (Router::$routes==null) {
new Router();
}
return Router::$routes;
}
public static function go($action,$params=null) {
$actions = explode("@", $action);
$c = strtolower($actions[0]);
$a = strtolower($actions[1]);
// set query sting to null
$queryString = null;
if(isset($params)) {
foreach ($params as $name => $value) {
$queryString .= '/'.$name.'//'.$value;
}
return APP_URL."$c/$a$queryString";
}
return APP_URL."$c/$a";
}
public static function checkRoutes($action,$method){
foreach (Router::getInstance()->routes as $valid) {
/* echo $valid->action . ' == ' . $action . '|||';
echo $valid->method . ' == ' . $method . '|||';*/
if ($valid->method == $method && $valid->action == $action) {
return true;
}
}
}
public static function inverseRoute($controller,$action) {
return ucfirst($controller)."@".$action;
}
public static function notFound($action,$method) {
die("Route not found:: $action with method $method");
}
}
我使用json_decode函数来解析stdClass()中的json对象。
json文件如下所示:
{"routes":[
{"action":"Frontend@index", "method":"GET"},
{"action":"Frontend@register", "method":"GET"},
{"action":"Frontend@blog", "method":"GET"}
]}
这样我可以使用他们的方法将路由列入白名单,并在找不到时返回404错误。
系统仍然是非常基础但是给予和想法和工作,希望有人会发现有用。