PHP 路由器、.htaccess 和重写查询字符串

PHP Router, .htaccess and rewriting query string

我尝试搜索这个问题,但没有找到解决我问题的方法 - 我几乎可以肯定我没有输入正确的搜索,因为我想这对其他人来说也是一个问题。如果我在打死马,请指出正确的方向,谢谢。

现有代码

我正在构建一种 MVC 框架。

.htaccess 将所有请求路由到 index.php.

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.php [QSA,L]
<?php

require_once "./core/init.php";

Router::create( "./core/router/routes.php" )->direct( Request::uri(), Request::method() );

我的router.class.php文件:

<?php

class Router {

    protected $routes = array(

        "GET" => array(),

        "POST" => array()

    );

    public static function create( $routes ) {

        $router = new static;

        include $routes;

        return $router;

    }

    public function get( $uri, $controller ) {

        $this->routes[ "GET" ][ $uri ] = $controller;

    }

    public function post( $uri, $controller ) {

        $this->routes[ "POST" ][ $uri ] = $controller;

    }

    public function direct( $uri, $method ) {

        if ( array_key_exists( $uri, $this->routes[ $method ] ) ) {

            include $this->routes[ $method ][ $uri ];

        } else {

            include $this->routes[ "GET" ][ "not-found" ];

        }

    }

}

路由在routes.php中定义如下(仅显示相关路由):

$router->get( "post", "controllers/get/post.controller.php" );

我的问题

当前导航到下面显示 post 并且 post 是使用 slug 从数据库中检索的。

/post?p=my-post-name

我如何重写我的路由器或 .htaccess 以具有与以下 URL 相同的 post?

/post/my-post-name

所以最后我通过在引导路由器之前创建检查解决了这个问题,但不确定这是否是 "right" 方式。

这基本上是根据数组检查 URI,如果 URI 包含这些设置值之一,则将其解构,最后一个值存储在名为 get 的变量中,然后重建 URI 减去假查询字符串:

// index.php

require_once "./core/init.php";

$uri = Request::uri();

/*
 * Fake query strings
 */
$uriParts = explode( "/", $uri );
$queryPages = array( "post", "category", "edit-post" );

foreach ( $queryPages as $queryPage ) {

    if ( in_array( $queryPage, $uriParts ) ) {

        $get = $uriParts[ count( $uriParts ) - 1 ];
        array_pop( $uriParts );
        $uri = "";

        for ( $i = 0; $i < ( count( $uriParts ) ); $i++ ) {

            $uri .= $uriParts[ $i ] . "/";

        }

        $uri = trim( $uri, "/" );
        break;

    }

}

Router::create( "./core/router/routes.php" )->direct( $uri, Request::method() );

以上适用于各种深度的 URI:

post/my-post
category/general
admin/posts/edit-post/my-post

"query string" 可以在带有 global $get; 的控制器中使用,然后用来代替 $_GET。这不适用于多个查询,但它非常适合我的要求。