PHP应用程序URL路由(PHP Application URL Routing)

2019-06-18 07:22发布

所以我写上,我想基础,我工作的一些应用程序框架(框架是存在的,所以我有一个环境的工作,和一个系统,将让我来说吧,使用单登录)

我想使这个框架,并应用它使用一个资源导向架构。

现在,我想创建一个URL路由类是可扩展的APP作家(也可能是由CMS应用的用户,但未来的WAYYYY在未来),我试图找出通过看这样做的最佳方式如何其他应用程序做到这一点。

Answer 1:

我更喜欢做我自己的格式,因为它是常识使用REG前。 我写了一个小的类,我用这让我窝这些REG前路由表。 我用使用类似这是通过继承来实现的东西,但它并不需要继承,所以我重写了它。

我做的一个关键和地图,我自己控制字符串一个reg前。 以下面的例子。 我访问/api/related/joe和我的路由器类创建一个新的对象ApiController并调用它的方法relatedDocuments(array('tags' => 'joe'));

// the 12 strips the subdirectory my app is running in
$index = urldecode(substr($_SERVER["REQUEST_URI"], 12)); 

Route::process($index, array(
    "#^api/related/(.*)$#Di"    => "ApiController/relatedDocuments/tags",

    "#^thread/(.*)/post$#Di"    => "ThreadController/post/title",
    "#^thread/(.*)/reply$#Di"   => "ThreadController/reply/title",
    "#^thread/(.*)$#Di"         => "ThreadController/thread/title",

    "#^ajax/tag/(.*)/(.*)$#Di"  => "TagController/add/id/tags",
    "#^ajax/reply/(.*)/post$#Di"=> "ThreadController/ajaxPost/id",
    "#^ajax/reply/(.*)$#Di"     => "ArticleController/newReply/id",
    "#^ajax/toggle/(.*)$#Di"    => "ApiController/toggle/toggle",

    "#^$#Di"                    => "HomeController",
));

为了保持向下的错误和简单了,你可以细分表。 这样,您就可以把路由表到它所控制的类。 以上面的例子,你可以在三级螺纹呼叫组合成一个单一的一个。

Route::process($index, array(
    "#^api/related/(.*)$#Di"    => "ApiController/relatedDocuments/tags",

    "#^thread/(.*)$#Di"         => "ThreadController/route/uri",

    "#^ajax/tag/(.*)/(.*)$#Di"  => "TagController/add/id/tags",
    "#^ajax/reply/(.*)/post$#Di"=> "ThreadController/ajaxPost/id",
    "#^ajax/reply/(.*)$#Di"     => "ArticleController/newReply/id",
    "#^ajax/toggle/(.*)$#Di"    => "ApiController/toggle/toggle",

    "#^$#Di"                    => "HomeController",
));

然后定义ThreadController ::路线是这样的。

function route($args) {
    Route::process($args['uri'], array(
        "#^(.*)/post$#Di"    => "ThreadController/post/title",
        "#^(.*)/reply$#Di"   => "ThreadController/reply/title",
        "#^(.*)$#Di"         => "ThreadController/thread/title",
    ));
}

你还可以定义你想要在右边你的路由串什么的默认值。 只是不要忘记记录他们,否则你会迷惑人。 目前,我正在打电话指数如果不包括右侧的功能名称。 这里是我当前的代码。 你可能想改变它,你怎么样和或默认动作来处理错误。



Answer 2:

另一种框架? - 反正...

诀窍是用路由是通过它遍布你的路由选择控制器。

你可能会想使用类似的东西,我在这里记载:

http://www.hm2k.com/posts/friendly-urls

第二个解决方案,您可以使用类似Zend框架的URL。



Answer 3:

使用Regexs列表匹配,我应该使用哪个对象

例如

^/users/[\w-]+/bookmarks/(.+)/$
^/users/[\w-]+/bookmarks/$
^/users/[\w-]+/$

优点:尼斯和简单,让我定义路由直接缺点:必须是有序的,不会因此很容易在添加新的东西(很容易出错)

这是,据我所知,Django的是怎么做的



Answer 4:

我想了很多框架使用Apache的mod_rewrite和前端控制器的组合。 随着mod_rewrite的,你可以打开一个URL是这样的:/人/得/ 3成这样:的index.php控制器=人与方法=获取&ID = 3。 index.php文件将执行的页面请求,基于给出的参数,路线前端控制器。



Answer 5:

正如你所期望的,也有很多的方法可以做到这一点。

例如,在超薄框架 ,路由引擎的一个实例可以是folllowing(基于模式${OBJECT}->${REQUEST METHOD}(${PATTERM}, ${CALLBACK})

$app->get("/Home", function() {
    print('Welcome to the home page');
}

$app->get('/Profile/:memberName', function($memberName) {
    print( 'I\'m viewing ' . $memberName . '\'s profile.' );
}

$app->post('/ContactUs', function() {
    print( 'This action will be fired only if a POST request will occure');
}

因此,初始化实例( $app )获得每个请求方法的方法(如GET,POST,放,删除等),并获得作为第一个参数和回调作为第二的路线。

这条路线可以得到令牌 - 这是“变”,将在运行时根据一些数据(如成员的姓名,文章编号,组织位置名称或任何 - 你知道,就像在每个路由控制器)改变。

就个人而言,我不喜欢这样,但我不认为这将是足够灵活的一种先进的框架。

由于我与ZF和目前的Yii工作,我有我已经为我工作的公司框架的一部分创建一个路由器的一个例子:

路由引擎是基于正则表达式(类似@ gradbot的一个),但有一个双向的对话,因此,如果您的客户端无法运行mod_rewrite的(在Apache),或增加他或她的服务器上重写规则,他或她仍然可以使用传统的URL查询字符串。

该文件包含一个阵列,每个的话,每个项目类似于该实施例中:

$_FURLTEMPLATES['login']    =   array(
    'i' => array( // Input - how the router parse an incomming path into query string params
        'pattern' => '@Members/Login/?@i',
        'matches' => array( 'Application' => 'Members', 'Module' => 'Login' ),
    ),
    'o' => array( // Output - how the router parse a query string into a route
        '@Application=Members(&|&)Module=Login/?@' => 'Members/Login/'
    )
);

您还可以使用更复杂的组合,如:

$_FURLTEMPLATES['article']  =   array(
    'i' => array(
        'pattern' => '@CMS/Articles/([\d]+)/?@i',
        'matches' => array( 'Application' => "CMS",
            'Module' => 'Articles',
            'Sector' => 'showArticle',
            'ArticleID' => '$1' ),
    ),
    'o' => array(
     '@Application=CMS(&|&)Module=Articles(&|&)Sector=showArticle(&|&)ArticleID=([\d]+)@' => 'CMS/Articles/$4'
    )
);

底线,因为我认为,是可能性是无止境的,它只是取决于你如何复杂的希望你的框架是,你想用它做什么。

如果,例如,只打算是一个Web服务或简单的网站包装 - 只是去写作的修身框架的风格 - 很容易和好看的代码。

但是,如果你想用它来开发复杂的网站,我觉得正则表达式是解决方案。

祝好运! :)



Answer 6:

你应该看看PUX https://github.com/c9s/Pux

这里是简介

<?php
require 'vendor/autoload.php'; // use PCRE patterns you need Pux\PatternCompiler class.
use Pux\Executor;

class ProductController {
    public function listAction() {
        return 'product list';
    }
    public function itemAction($id) { 
        return "product $id";
    }
}
$mux = new Pux\Mux;
$mux->any('/product', ['ProductController','listAction']);
$mux->get('/product/:id', ['ProductController','itemAction'] , [
    'require' => [ 'id' => '\d+', ],
    'default' => [ 'id' => '1', ]
]);
$mux->post('/product/:id', ['ProductController','updateAction'] , [
    'require' => [ 'id' => '\d+', ],
    'default' => [ 'id' => '1', ]
]);
$mux->delete('/product/:id', ['ProductController','deleteAction'] , [
    'require' => [ 'id' => '\d+', ],
    'default' => [ 'id' => '1', ]
]);
$route = $mux->dispatch('/product/1');
Executor::execute($route);


Answer 7:

默认情况下,Zend的MVC框架采用如下的结构

/router/controller/action/key1/value1/key2/value2

其中router在路由器文件(通过映射mod_rewritecontroller是从由从派生的类中定义的控制器的动作的处理程序Zend_Controller_Actionaction引用一个方法在控制器,命名actionAction 。键/值对可以去任何顺序并提供给所述的操作方法作为关联数组。

我已经使用过类似的东西在我自己的代码,到目前为止,它的工作相当不错。



Answer 8:

尝试采取看看MVC模式。
Zend框架使用它例如,也CakePHP的,笨,...

我个人不喜欢MVC模型,但它的大部分为“信息查看网”组件实现的时间。

这个决定非常依赖于偏好...



文章来源: PHP Application URL Routing