前言
读过一篇关于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对应用户的一篇博客文章
方案引用自原文:
'router' => 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' ), ), 'may_terminate' => true, 'child_routes' => array( 'blog' => array( 'type' => 'segment', 'options' => array( 'route' => 'blog[/]', 'constraints' => array( ), 'defaults' => array( 'action' => 'blog' ) ), 'may_terminate' => true, 'child_routes' => array( 'post' => array( 'type' => 'segment', 'options' => array( 'route' => '[:post_id][/]', 'constraints' => array( 'post_id' => '[a-za-z0-9_-]+' ), 'defaults' => array( 'action' => 'post' ) ), 'may_terminate' => true, ), ), ), ), //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。
修改公共配置文件tp\application\common\conf\config.php:
<?php return array( // 开启路由 'url_router_on' => 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', ), ); ?>
创建文件tp\application\home\controller\usercontroller.class.php:
<?php namespace home\controller; use think\controller; class usercontroller extends controller { public function url() { $name = 'jing'; $blogid = 1; $urls = array( u('/user'), u("/user/{$name}"), u("/user/{$name}/blog"), u("/user/{$name}/blog/{$blogid}"), ); foreach ($urls as $url) { echo "<a href=\"{$url}\">{$url}<a/><br />\n"; } } public function index() { echo '我是用户列表^_^'; } public function show($name) { echo "欢迎你,{$name}"; } } ?>
创建文件tp\application\home\controller\blogcontroller.class.php:
<?php namespace home\controller; use think\controller; class blogcontroller extends controller { public function index($name) { echo "这是{$name}的博客列表"; } public function show($blog_id, $name) { echo "{$name}的这篇博客的id为{$blog_id}"; } } ?>
访问:
输出:
访问上面4个链接,依次返回:
我是用户列表^_^
欢迎你,jing
这是jing的博客列表
jing的这篇博客的id为1
下面其他框架,也同样输出以上内容。
zend framework 2
使用zf2骨架程序创建一个zf2项目:
composer create-project --stability="dev" zendframework/skeleton-application zf2
修改默认模块application的配置文件zf2\module\application\config\module.config.php:
<?php /** * zend framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zendskeletonapplication for the canonical source repository * @copyright copyright (c) 2005-2015 zend technologies usa inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd new bsd license */ return array( 'router' => array( 'routes' => array( 'home' => array( 'type' => 'zend\mvc\router\http\literal', 'options' => array( 'route' => '/url', 'defaults' => array( 'controller' => 'application\controller\user', '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__' => 'application\controller', 'controller' => 'index', 'action' => 'index', ), ), 'may_terminate' => true, '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[/]', 'defaults' => array( '__namespace__' => 'application\controller', 'controller' => 'user', 'action' => 'index', ), ), 'may_terminate' => true, 'child_routes' => array( 'user' => array( 'type' => 'segment', 'options' => array( 'route' => '[:name][/]', 'constraints' => array( 'name' => '[a-za-z0-9_-]+', ), 'defaults' => array( 'action' => 'show', ), ), 'may_terminate' => true, 'child_routes' => array( 'blog_list' => array( 'type' => 'segment', 'options' => array( 'route' => 'blog[/]', 'constraints' => array( ), 'defaults' => array( 'controller' => 'blog', 'action' => 'index', ) ), 'may_terminate' => true, 'child_routes' => array( 'blog' => array( 'type' => 'segment', 'options' => array( 'route' => '[:blog_id]', 'constraints' => array( 'blog_id' => '[0-9]+', ), 'defaults' => array( 'action' => 'show', ) ), 'may_terminate' => true, ), ), ), ), ), ), ), ), ), 'service_manager' => array( 'abstract_factories' => array( 'zend\cache\service\storagecacheabstractservicefactory', 'zend\log\loggerabstractservicefactory', ), '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( 'application\controller\index' => 'application\controller\indexcontroller', 'application\controller\user' => 'application\controller\usercontroller', 'application\controller\blog' => 'application\controller\blogcontroller', ), ), '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官方发布了一个骨架程序的原因。
创建文件zf2\module\application\src\application\controller\usercontroller.php:
<?php namespace application\controller; use zend\mvc\controller\abstractactioncontroller; use zend\view\model\viewmodel; class usercontroller extends abstractactioncontroller { public function urlaction() { $name = 'jing'; $blogid = 1; $urls = array( $this->url()->fromroute('user_list'), $this->url()->fromroute('user_list/user', array('name' => $name)), $this->url()->fromroute('user_list/user/blog_list', array('name' => $name)), $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; } } ?>
创建文件zf2\module\application\src\application\controller\blogcontroller.php:
<?php namespace application\controller; use zend\mvc\controller\abstractactioncontroller; use zend\view\model\viewmodel; class blogcontroller extends abstractactioncontroller { public function indexaction() { $username = $this->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()。如果你知道可以禁用视图的办法,请告诉我。
创建文件zf2\module\application\view\application\user\url.phtml:
<?php foreach ($urls as $url): ?> <a href="<?php echo $url;?>"><?php echo $url;?><a/><br /> <?php endforeach; ?>
创建文件zf2\module\application\view\application\user\index.phtml:
我是用户列表^_^
创建文件zf2\module\application\view\application\user\show.phtml:
欢迎你,<?php echo $username; ?>
创建文件zf2\module\application\view\application\blog\index.phtml:
这是<?php echo $username; ?>的博客列表
创建文件zf2\module\application\view\application\blog\show.phtml:
yaf
安装yaf
使用代码生成工具创建yaf项目
修改启动文件yaf\application\bootstrap.php,修改其中的_initroute方法:
$router = yaf_dispatcher::getinstance()->getrouter(); $route0 = new yaf_route_rewrite('url', array( 'controller' => 'user', 'action' => 'url', ), array() ); $route1 = new yaf_route_rewrite('user', array( 'controller' => 'user', 'action' => 'index', ), array() ); $route2 = new yaf_route_regex('#user/([a-za-z0-9_-]+)#', array( 'controller' => 'user', 'action' => 'show', ), array(1 => 'name',) ); $route3 = new yaf_route_regex('#user/([a-za-z0-9_-]+)/blog#', array( 'controller' => 'blog', 'action' => 'index', ), array(1 => 'name',) ); $route4 = new yaf_route_regex('#user/([a-za-z0-9_-]+)/blog/([0-9]+)#', array( 'controller' => 'blog', 'action' => 'show', ), array(1 => 'name', 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。
在配置文件中添加配置项yaf\conf\application.ini:
创建文件yaf\application\controllers\user.php:
<?php class usercontroller extends yaf_controller_abstract { public function urlaction() { $name = 'jing'; $blogid = 1; $app = yaf_application::app(); $projectname = $app->getconfig()->project->name; $urls = array( "/{$projectname}/user", "/{$projectname}/user/{$name}", "/{$projectname}/user/{$name}/blog", "/{$projectname}/user/{$name}/blog/{$blogid}", ); foreach ($urls as $url) { echo "<a href=\"{$url}\">{$url}<a/><br />\n"; } return false; } public function indexaction() { echo '我是用户列表^_^'; // 禁用视图模板 return false; } public function showaction($name) { echo "欢迎你,{$name}"; return false; } }
创建文件yaf\application\controllers\blog.php:
yaf的action支持参数绑定,是按变量名绑定的。$name、$blogid要和路由中配置的名称一样,而和参数顺序无关。
laravel
新建laravel项目:
清除合并文件。在目录laravel\vendor\下有个文件compiled.php,这个文件是为了减少io提高框架性能,将很多类文件合并到一个文件中而生存的。在开发环境下,应该删除该文件,否则修改了一些文件发现没有效果,其实是因为文件已经合并缓存了。
清除命令:
在生产环境中应该开启,以提升性能:
修改路由文件laravel\app\http\routes.php:
查看路由定义情况:
输出:
定义路由变量全局模式,修改文件laravel\app\providers\routeserviceprovider.php中的boot方法:
parent::boot($router);
}
创建usercontroller控制器:
laravel帮我们在laravel\app\http\controllers目录下创建了文件usercontroller.php,文件中已经为我们写好一部分骨架代码。修改文件laravel\app\http\controllers\usercontroller.php:
创建blogcontroller控制器:
修改文件laravel\app\http\controllers\blogcontroller.php:
laravel的action也支持参数绑定,是按变量顺序绑定的,和变量名无关。
后语
我是laravel粉,但是我也没有想黑其他框架的意思,大家有兴趣也可以用自己熟悉的框架来实现这个小例子,写了记得@我,语言不限。
以上所述就是本文的全部内容了,希望大家能够喜欢。
请您花一点时间将文章分享给您的朋友或者留下评论。我们将会由衷感谢您的支持!
如对本文有疑问, 点击进行留言回复!!
[ACTF2020 新生赛]Include 1【文件包含】【读取代码】
算法题解 - 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者组
推荐一个程序员必备网站之一:Dev Hints ,非常实用!
网友评论