PHP应用程序URL路由
因此,我正在编写一个框架,我希望以此为基础来开发一些我正在使用的应用程序(该框架在那里,所以我有一个可以使用的环境,并且该系统可以让我使用例如一个登录)
我要创建这个框架,并且它的应用程序都使用面向资源的架构。
现在,我想创建一个URL路由类,该类可以由APP编写器(也可能由CMS App用户)扩展,但我想通过查看以下方法找出最佳方法其他应用程序如何做到这一点。
解决方案
使用正则表达式列表来匹配我应该使用的对象
例如
^/users/[\w-]+/bookmarks/(.+)/$ ^/users/[\w-]+/bookmarks/$ ^/users/[\w-]+/$
优点:简单明了,让我直接定义路线
缺点:必须订购,而不是很容易添加新东西(容易出错)
这就是afaik,Django是如何做到的
尝试看一下MVC模式。
例如,Zend Framework会使用它,但CakePHP,CodeIgniter也会使用它。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
我个人不喜欢MVC模型,但是大多数情况下,它是作为"用于Web的视图"组件实现的。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。都是。
这个决定很大程度上取决于偏好。
我认为许多框架都结合使用了Apache的mod_rewrite和前端控制器。使用mod_rewrite,我们可以将以下网址转换为:/ people / get / 3:
index.php?controller = people&method = get&id = 3. Index.php将实现前端控制器,该控制器根据给定的参数路由页面请求。
Zend的MVC框架默认使用类似
/router/controller/action/key1/value1/key2/value2
其中," router"是路由器文件(通过" mod_rewrite"映射," controller"来自控制器操作处理程序,该处理程序由从" Zend_Controller_Action"派生的类定义," action"引用了控制器中名为" actionAction"的方法键/值对可以按任何顺序排列,并且可以作为关联数组用于操作方法。
过去,我在自己的代码中使用了类似的方法,到目前为止,它的运行情况还不错。
我比较喜欢使用reg ex而不是制作自己的格式,因为这是常识。我写了一个小类,使我可以嵌套这些正则表达式路由表。我曾经使用过通过继承实现的类似内容,但是它不需要继承,因此我重写了它。
我对一个键进行正则表达式,然后映射到我自己的控制字符串。请看下面的例子。我访问/ 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 :: route就像这样。
function route($args) { Route::process($args['uri'], array( "#^(.*)/post$#Di" => "ThreadController/post/title", "#^(.*)/reply$#Di" => "ThreadController/reply/title", "#^(.*)$#Di" => "ThreadController/thread/title", )); }
我们也可以在右侧为路由字符串定义所需的任何默认值。只是不要忘了将它们记录下来,否则我们将使人们感到困惑。如果我们在右侧未包含函数名称,则当前正在调用索引。这是我当前的代码。我们可能需要更改它以处理我们喜欢的错误和/或者默认操作。
还有一个框架? -反正...
路由的窍门是将其全部传递给路由控制器。
我们可能想要使用类似于我在此处记录的内容:
http://www.hm2k.com/posts/friendly-urls
第二种解决方案使我们可以使用类似于Zend Framework的URL。