如何从一个路由器进行很好的rewrited网址很好、路由器、网址、rewrited

2023-09-02 00:37:05 作者:安心,安不下心°

我正在做一个工具包PHP应用程序。我做一个基于某种约定的路由系统,效果很好,但我想了解如何使mod_rewrite规则或任何其他的东西,最终使URL很好看,良好的搜索引擎优化。

I'm making a toolkit for php applications. I've a made a routing system based on some conventions, it works well but i would like to learn how to make mod_rewrite rules or any other stuff to finally make the url good to see and good for seo.

这条路线系统开始从集合的应用程序,URL根的配置文件。

The route system starts from a config file that set the app and url roots.

$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参数控制器=放大器控制器@行动的情况;?行动=

The route always get start from index.php, wich makes instances of controllers@actions from GET parameters controllers=?&action=?

这是在index.php

This is the 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();
    }

这让选择什么样的控制器和什么样的行动,路由器必须调用。

This allow to select what controller and what action the router must call.

路由器功能,从这里的settings.php根获得APP URL。你给即时通讯这两个控制器@行动PARAMS为字符串,并使得网址如下所示: ?index.php文件控制器= X&放大器;行动= Y&放大器; [参数...]

The router function here get the APP URL from settings.php in the root. You give im the two controllers@action params as string and it make the URL like so: index.php?controller=X&action=Y&[params...]

<?php

要求'./settings.php';

require './settings.php';

    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);
    }

在模板文件我称之为路由器('控制'行动),以检索URL的行动,并通过GET / POST数据(从index.php文件即放的他们收集到的方法签名为数组)。

In templates file i call router('controller,'action') to retrive url's to actions and also pass GET/POST data (collected from index.php that put's them into the method signature as array).

不要怪我用全球POST / GET无滤波我还在发展中的东西,安全的事情会之后作出。)的

我想什么要问,如果有人可以分享关于如何使pretty的网址类似的网站/网页/操作的一些想法.... 例如www.site.com/blog/post?id=1

What i would like to ask if someone could share some thoughts on how to make pretty urls like site/page/action.... For example www.site.com/blog/post?id=1

(实际上是在路由器功能($ query_data N个PARAMS)以这种方式工作,你通过数组['身份证'=>'1'],你会得到?ID = 1)

(Actually the N params in the router function ($query_data) works this way, you pass array['id' => '1'] and you get ?id=1)

什么是好好网址最好的策略是什么? 非常感谢你,还在学习PHP。

What are best strategies to make good urls? Thank you so much, still learning PHP.

如果有做这种事情只是给你的反馈最好的方式。

If there are best way to do such things just give your feedback.

推荐答案

我发现自己的问题的答案,我在这里发布,也许这是很有用的。

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

我的根添加一个.htaccess文件:

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

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

这将返回每个请求根/ index.php文件。

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

索引文件收集来自HTTP请求的路径,检查路径存在的routes.json文件。

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

网址是这样写的: site.com/controller/action。 GET参数的写法如下 site.com/controller/action/[params] / [值] ......这个输出例如site.com/blog/post/id/1 这应该是还罚款休息。

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.

下面的的index.php

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 PlayPhpClassesRequest();
    // 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_de code函数解析stdClass的JSON对象()。

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

JSON文件看起来是这样的:

The json file looks like this:

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

这样我可以白名单与他们的方法路线,虽然没有找到返回404错误。

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.