如何从路由器

时间:2015-10-07 21:54:47

标签: php .htaccess mod-rewrite url-rewriting url-routing

我正在为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。

如果有最好的方式来做这些事情,请提供反馈。

1 个答案:

答案 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错误。

系统仍然是非常基础但是给予和想法和工作,希望有人会发现有用。