how to make nice rewrited urls from a router

烂漫一生 提交于 2019-12-02 04:52:39

I found myself an answer to the question, i post here maybe it's useful.

I've added a .htaccess file in the root:

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

This will return each request to the root/index.php file.

Index file collect routes from the HTTP request, check if the route exist in the "routes.json" file.

URL are written in this way: site.com/controller/action. GET params are written as follows site.com/controller/action/[params]/[value]...... This output for example site.com/blog/post/id/1 That should be also fine for REST.

Here the 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);


}

The Router class:

    <?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");

    }



}

I use the json_decode function to parse the json object in stdClass().

The json file looks like this:

    {"routes":[
  {"action":"Frontend@index", "method":"GET"},
  {"action":"Frontend@register", "method":"GET"},
  {"action":"Frontend@blog", "method":"GET"}
]}

This way i can whitelist routes with their methods and return 404 errors while not found.

System is still quite basic but gives and idea and works, hope someone will find useful.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!