ThinkPHP、ZF2、Yaf、Laravel框架路由大比拼
前言 读过一篇关于Zend Framework2的技术文章《ZF2多级树形路由Route配置实例》,是介绍路由配置的。我觉得很有意思,这是的需求: /user对应用户列表页面 /user/:user_id对应用户的个人主页,比如 /user/AlloVince 就对应AlloVince用户的个人主页 /user/:user_id/blog/对应用户的博客列表页面,比如 /user/AlloVince/blog 就会列出AlloVince写过的Blog /user/:user_id/blog/:blog_id对应用户的一篇博客文章 方案引用自原文: array(
'routes' => array(
'user' => array(
'type' => 'Segment','options' => array(
'route' => '/user[/]','defaults' => array(
'controller' => 'UserController','action' => 'index',),'may_terminate' => true,'child_routes' => array(
'profile' => array(
'type' => 'Segment','options' => array(
'route' => '[:id][/]','constraints' => array(
'id' => '[a-zA-Z0-9_-]+'
),'defaults' => array(
'action' => 'get'
),'child_routes' => array(
'blog' => array(
'type' => 'Segment','options' => array(
'route' => 'blog[/]','constraints' => array(
),'defaults' => array(
'action' => 'blog'
)
),'child_routes' => array(
'post' => array(
'type' => 'Segment','options' => array(
'route' => '[:post_id][/]','constraints' => array(
'post_id' => '[a-zA-Z0-9_-]+'
),'defaults' => array(
'action' => 'post'
)
),//profile child_routes end
),//profile end
),//user child_routes end
),//user end
),
看了这篇文章后,我打算使用我用过的PHP框架来实现这个路由需求。 ThinkPHP新建一个ThinkPHP项目: 代码如下: 命令行显示我安装的是3.2.2 Installing topthink/thinkphp (3.2.2) 我看ThinkPHP官网最新稳定版本是3.2.3。 我特意去packagist官网查了一下,库中稳定版确实是3.2.2。 我得使用3.2.3。为什么我特别纠结这一点哩?因为: 3.2的路由功能是针对模块设置的,所以URL中的模块名不能被路由,路由定义也通常是放在模块配置文件中。 3.2.3版本开始增加全局路由定义支持,可以在项目的公共配置文件中定义路由。 也就是说,路由重写的部分是Controller和Action部分,Moudle还是存在。 我希望的是/user,而不是home/user。(ThinkPHP中默认Module是Home,'DEFAULT_MODULE' => 'Home',可以修改) 当然,这个问题也可以修改.htaccess文件的解决。但是,我还是决定安装3.2.3。 在ThinkPHP官网下载最新的包,解压。 使用浏览器访问一下项目的入口文件,让ThinkPHP自动生成了一个默认的应用模块Home。 修改公共配置文件tpApplicationCommonConfconfig.php: true,// URL访问模式,可选参数0、1、2、3,代表以下四种模式:
// 0 (普通模式); 1 (PATHINFO 模式); 2 (REWRITE 模式); 3 (兼容模式) 默认为PATHINFO 模式
'URL_MODEL' => 2,// URL伪静态后缀设置,为空表示可以支持所有的静态后缀
// 使用U函数生成URL时会不带后缀
'URL_HTML_SUFFIX' => '',// URL变量绑定到Action方法参数,默认为true
'URL_PARAMS_BIND' => true,// URL变量绑定的类型 0 按变量名绑定 1 按变量顺序绑定,默认为0
'URL_PARAMS_BIND_TYPE' => 0,// 路由配置
'URL_ROUTE_RULES' => array(
'/^url$/' => 'Home/User/url','/^user$/' => 'Home/User/index','/^user/([a-zA-Z0-9_-]+)$/' => 'Home/User/show?name=:1','/^user/([a-zA-Z0-9_-]+)/blog$/' => 'Home/Blog/index?name=:1','/^user/([a-zA-Z0-9_-]+)/blog/([0-9]+)$/' => 'Home/Blog/show?name=:1&blog_id=:2',);
?>
创建文件tpApplicationHomeControllerUserController.class.php: n"; } } public function index() { echo '我是用户列表^_^'; } public function show($name) { echo "欢迎你,{$name}"; } } ?>创建文件tpApplicationHomeControllerBlogController.class.php: 访问: 输出: 代码如下:
访问上面4个链接,依次返回: 我是用户列表^_^ 欢迎你,jing 这是jing的博客列表 jing的这篇博客的id为1 下面其他框架,也同样输出以上内容。 Zend Framework 2使用ZF2骨架程序创建一个ZF2项目: composer create-project --stability="dev" zendframework/skeleton-application zf2 修改默认模块Application的配置文件zf2moduleApplicationconfigmodule.config.php: array(
'routes' => array(
'home' => array(
'type' => 'ZendMvcRouterHttpLiteral','options' => array(
'route' => '/url','defaults' => array(
'controller' => 'ApplicationControllerUser','action' => 'url',// The following is a route to simplify getting started creating
// new controllers and actions without needing to create a new
// module. Simply drop new controllers in,and you can access them
// using the path /application/:controller/:action
'application' => array(
'type' => 'Literal','options' => array(
'route' => '/application','defaults' => array(
'__NAMESPACE__' => 'ApplicationController','controller' => 'Index','child_routes' => array(
'default' => array(
'type' => 'Segment','options' => array(
'route' => '/[:controller[/:action]]','constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*','action' => '[a-zA-Z][a-zA-Z0-9_-]*','defaults' => array(
),'user_list' => array(
'type' => 'Segment','options' => array(
'route' => '/user[/]','controller' => 'User','child_routes' => array(
'user' => array(
'type' => 'Segment','options' => array(
'route' => '[:name][/]','constraints' => array(
'name' => '[a-zA-Z0-9_-]+','defaults' => array(
'action' => 'show','child_routes' => array(
'blog_list' => array(
'type' => 'Segment','options' => array(
'route' => 'blog[/]','constraints' => array(
),'defaults' => array(
'controller' => 'Blog',)
),'child_routes' => array(
'blog' => array(
'type' => 'Segment','options' => array(
'route' => '[:blog_id]','constraints' => array(
'blog_id' => '[0-9]+','defaults' => array(
'action' => 'show',)
),'service_manager' => array(
'abstract_factories' => array(
'ZendCacheServiceStorageCacheAbstractServiceFactory','ZendLogLoggerAbstractServiceFactory','aliases' => array(
'translator' => 'MvcTranslator','translator' => array(
'locale' => 'en_US','translation_file_patterns' => array(
array(
'type' => 'gettext','base_dir' => __DIR__ . '/../language','pattern' => '%s.mo','controllers' => array(
'invokables' => array(
'ApplicationControllerIndex' => 'ApplicationControllerIndexController','ApplicationControllerUser' => 'ApplicationControllerUserController','ApplicationControllerBlog' => 'ApplicationControllerBlogController','view_manager' => array(
'display_not_found_reason' => true,'display_exceptions' => true,'doctype' => 'HTML5','not_found_template' => 'error/404','exception_template' => 'error/index','template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml','application/index/index' => __DIR__ . '/../view/application/index/index.phtml','error/404' => __DIR__ . '/../view/error/404.phtml','error/index' => __DIR__ . '/../view/error/index.phtml','template_path_stack' => array(
__DIR__ . '/../view',// Placeholder for console routes
'console' => array(
'router' => array(
'routes' => array(
),);
?>
这个文件是骨架程序中自带的,我只是修改了router部分和controllers部分。要我写这么长的文件,那就太为难我了。这也是ZF官方发布了一个骨架程序的原因。 创建文件zf2moduleApplicationsrcApplicationControllerUserController.php: url()->fromRoute('user_list'),$this->url()->fromRoute('user_list/user',array('name' => $name)),$this->url()->fromRoute('user_list/user/blog_list',$this->url()->fromRoute('user_list/user/blog_list/blog',array('name' => $name,'blog_id' => $blogId)),);
$view = new ViewModel(compact('urls'));
$view->setTerminal(true);
return $view;
}
public function indexAction() {
$view = new ViewModel();
// 禁用布局模板
$view->setTerminal(true);
return $view;
}
public function showAction() {
$username = $this->params()->fromRoute('name');
$view = new ViewModel(compact('username'));
$view->setTerminal(true);
return $view;
}
}
?>
创建文件zf2moduleApplicationsrcApplicationControllerBlogController.php: params()->fromRoute('name');
$view = new ViewModel(compact('username'));
$view->setTerminal(true);
return $view;
}
public function showAction() {
$username = $this->params()->fromRoute('name');
$blogId = $this->params()->fromRoute('blog_id');
$view = new ViewModel(compact('username','blogId'));
$view->setTerminal(true);
return $view;
}
}
?>
zf2不支持Action参数绑定,ThinkPHP不仅支持绑定,还支持2种绑定方式:按变量名绑定和按变量顺序绑定。 zf2中Action必须得返回视图,除非exit()。如果你知道可以禁用视图的办法,请告诉我。 创建文件zf2moduleApplicationviewapplicationuserurl.phtml:
">
创建文件zf2moduleApplicationviewapplicationuserindex.phtml: 我是用户列表^_^ 创建文件zf2moduleApplicationviewapplicationusershow.phtml: 欢迎你, 创建文件zf2moduleApplicationviewapplicationblogindex.phtml: 这是的博客列表 创建文件zf2moduleApplicationviewapplicationblogshow.phtml: 代码如下: 的这篇博客的id为
Yaf安装Yaf 使用代码生成工具创建Yaf项目 修改启动文件yafapplicationBootstrap.php,修改其中的_initRoute方法: getRouter();
$route0 = new Yaf_Route_Rewrite('url',array(
'controller' => 'User',array()
);
$route1 = new Yaf_Route_Rewrite('user',array()
);
$route2 = new Yaf_Route_Regex('#user/([a-zA-Z0-9_-]+)#','action' => 'show',array(1 => 'name',)
);
$route3 = new Yaf_Route_Regex('#user/([a-zA-Z0-9_-]+)/blog#',array(
'controller' => 'Blog',)
);
$route4 = new Yaf_Route_Regex('#user/([a-zA-Z0-9_-]+)/blog/([0-9]+)#',2 => 'blogId',)
);
$router->addRoute('url',$route0);
$router->addRoute('user_list',$route1);
$router->addRoute('user',$route2);
$router->addRoute("blog_list",$route3);
$router->addRoute("blog",$route4);
Yaf有路由功能,但是没有根据路由名生成URL的方法。所以我定义了一个项目名,用于拼接URL。 在配置文件中添加配置项yafconfapplication.ini: 代码如下: 创建文件yafapplicationcontrollersUser.php: getConfig()->project->name;
$urls = array(
"/{$projectName}/user","/{$projectName}/user/{$name}","/{$projectName}/user/{$name}/blog","/{$projectName}/user/{$name}/blog/{$blogId}",);
foreach ($urls as $url) {
echo "
n"; } return false; } public function indexAction() { echo '我是用户列表^_^'; // 禁用视图模板 return false; } public function showAction($name) { echo "欢迎你,{$name}"; return false; } } 创建文件yafapplicationcontrollersBlog.php: 代码如下: Yaf的Action支持参数绑定,是按变量名绑定的。$name、$blogId要和路由中配置的名称一样,而和参数顺序无关。 Laravel新建Laravel项目: 代码如下: 清除合并文件。在目录laravelvendor下有个文件compiled.php,这个文件是为了减少IO提高框架性能,将很多类文件合并到一个文件中而生存的。在开发环境下,应该删除该文件,否则修改了一些文件发现没有效果,其实是因为文件已经合并缓存了。 清除命令: 代码如下: 在生产环境中应该开启,以提升性能: 代码如下: 修改路由文件laravelappHttproutes.php: 代码如下: ));
Route::get('/user',array('uses' => ));
Route::get('/user/{username}',array('uses' => ));
Route::get('/user/{username}/blog',array(
'as' => 'blog_list',
'uses' => ,
));
Route::get('/user/{username}/blog/{blogId}',array(
'as' => 'blog',
'uses' => ,
))->where(array('blogId' => '[0-9]+'));
查看路由定义情况: 代码如下: 输出: 代码如下: 定义路由变量全局模式,修改文件laravelappProvidersRouteServiceProvider.php中的boot方法: 代码如下: pattern('username','[a-zA-Z0-9_-]+');
parent::boot($router); } 创建UserController控制器: 代码如下: Laravel帮我们在laravelappHttpControllers目录下创建了文件UserController.php,文件中已经为我们写好一部分骨架代码。修改文件laravelappHttpControllersUserController.php: 代码如下: n";
}
}
public function getIndex() {
echo '我是用户列表^_^';
}
public function getShow($name) {
echo "欢迎你,{$name}";
}
}
创建BlogController控制器: 代码如下: 修改文件laravelappHttpControllersBlogController.php: 代码如下: Laravel的Action也支持参数绑定,是按变量顺序绑定的,和变量名无关。 后语我是Laravel粉,但是我也没有想黑其他框架的意思,大家有兴趣也可以用自己熟悉的框架来实现这个小例子,写了记得@我,语言不限。 以上所述就是本文的全部内容了,希望大家能够喜欢。 请您花一点时间将文章分享给您的朋友或者留下评论。我们将会由衷感谢您的支持! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |