当前位置:首页 > CMS教程 > Thinkphp > 列表

ThinkPHP、ZF2、Yaf、Laravel框架路由大比拼

发布:smiling 来源: PHP粉丝网  添加日期:2021-05-18 10:51:30 浏览: 评论:0 

这篇文章主要介绍了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对应用户的一篇博客文章

方案引用自原文:

  1. 'router' => array
  2.   'routes' => array
  3.     'user' => array
  4.       'type' => 'Segment'
  5.       'options' => array
  6.         'route' => '/user[/]'
  7.         'defaults' => array
  8.           'controller' => 'UserController'
  9.           'action' => 'index'
  10.         ), 
  11.       ), 
  12.       'may_terminate' => true, 
  13.       'child_routes' => array
  14.         'profile' => array
  15.           'type' => 'Segment'
  16.           'options' => array
  17.             'route' => '[:id][/]'
  18.             'constraints' => array
  19.               'id' => '[a-zA-Z0-9_-]+' 
  20.             ), 
  21.             'defaults' => array
  22.               'action' => 'get' 
  23.             ), 
  24.           ), 
  25.           'may_terminate' => true, 
  26.           'child_routes' => array
  27.             'blog' => array
  28.               'type' => 'Segment'
  29.               'options' => array
  30.                 'route' => 'blog[/]'
  31.                 'constraints' => array
  32.                 ), 
  33.                 'defaults' => array
  34.                   'action' => 'blog' 
  35.                 ) 
  36.               ), 
  37.               'may_terminate' => true, 
  38.               'child_routes' => array
  39.                 'post' => array
  40.                   'type' => 'Segment'
  41.                   'options' => array
  42.                     'route' => '[:post_id][/]'
  43.                     'constraints' => array
  44.                       'post_id' => '[a-zA-Z0-9_-]+' 
  45.                     ), 
  46.                     'defaults' => array
  47.                       'action' => 'post' 
  48.                     ) 
  49.                   ), 
  50.                   'may_terminate' => true, 
  51.                 ), 
  52.               ), 
  53.             ), 
  54.           ), //profile child_routes end 
  55.         ), //profile end 
  56.       ), //user child_routes end 
  57.     ), //user end 
  58.   ), 
  59. ), 

看了这篇文章后,我打算使用我用过的PHP框架来实现这个路由需求。

ThinkPHP

新建一个ThinkPHP项目:

composer create-project topthink/thinkphp tp --prefer-dist

命令行显示我安装的是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:

  1. <?php 
  2. return array
  3.   // 开启路由 
  4.   'URL_ROUTER_ON' => true, 
  5.   // URL访问模式,可选参数0、1、2、3,代表以下四种模式: 
  6.   // 0 (普通模式); 1 (PATHINFO 模式); 2 (REWRITE 模式); 3 (兼容模式) 默认为PATHINFO 模式 
  7.   'URL_MODEL' => 2, 
  8.   // URL伪静态后缀设置,为空表示可以支持所有的静态后缀 
  9.   // 使用U函数生成URL时会不带后缀 
  10.   'URL_HTML_SUFFIX' => ''
  11.   // URL变量绑定到Action方法参数,默认为true 
  12.   'URL_PARAMS_BIND' => true, 
  13.   // URL变量绑定的类型 0 按变量名绑定 1 按变量顺序绑定,默认为0 
  14.   'URL_PARAMS_BIND_TYPE' => 0, 
  15.   // 路由配置 
  16.   'URL_ROUTE_RULES' => array
  17.     '/^url$/' => 'Home/User/url'
  18.     '/^user$/' => 'Home/User/index'
  19.     '/^user\/([a-zA-Z0-9_-]+)$/' => 'Home/User/show?name=:1'
  20.     '/^user\/([a-zA-Z0-9_-]+)\/blog$/' => 'Home/Blog/index?name=:1'
  21.     '/^user\/([a-zA-Z0-9_-]+)\/blog\/([0-9]+)$/' => 'Home/Blog/show?name=:1&blog_id=:2'
  22.   ), 
  23. ); 
  24. ?> 

创建文件tp\Application\Home\Controller\UserController.class.php:

  1. <?php 
  2. namespace Home\Controller; 
  3. use Think\Controller; 
  4. class UserController extends Controller { 
  5.   public function url() { 
  6.     $name = 'jing'
  7.     $blogId = 1; 
  8.     $urls = array
  9.       U('/user'), 
  10.       U("/user/{$name}"), 
  11.       U("/user/{$name}/blog"), 
  12.       U("/user/{$name}/blog/{$blogId}"), 
  13.     ); 
  14.     foreach ($urls as $url) { 
  15.       echo "<a href=\"{$url}\">{$url}<a/><br />\n"
  16.     } 
  17.   } 
  18.   public function index() { 
  19.     echo '我是用户列表^_^'
  20.   } 
  21.   public function show($name) { 
  22.     echo "欢迎你,{$name}"
  23.   } 
  24. ?> 

创建文件tp\Application\Home\Controller\BlogController.class.php:

  1. <?php 
  2. namespace Home\Controller; 
  3. use Think\Controller; 
  4. class BlogController extends Controller { 
  5.   public function index($name) { 
  6.     echo "这是{$name}的博客列表"
  7.   } 
  8.   public function show($blog_id$name) { 
  9.     echo "{$name}的这篇博客的id为{$blog_id}"
  10.   } 
  11. ?> 

访问:http://127.0.0.1/tp/url

输出:

  1. <a href="/tp/user">/tp/user<a/><br /> 
  2. <a href="/tp/user/jing">/tp/user/jing<a/><br /> 
  3. <a href="/tp/user/jing/blog">/tp/user/jing/blog<a/><br /> 
  4. <a href="/tp/user/jing/blog/1">/tp/user/jing/blog/1<a/><br /> 

访问上面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:

  1. <?php 
  2. /** 
  3.  * Zend Framework (http://framework.zend.com/) 
  4.  * 
  5.  * @link   http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository 
  6.  * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 
  7.  * @license  http://framework.zend.com/license/new-bsd New BSD License 
  8.  */ 
  9. return array
  10.   'router' => array
  11.     'routes' => array
  12.       'home' => array
  13.         'type' => 'Zend\Mvc\Router\Http\Literal'
  14.         'options' => array
  15.           'route' => '/url'
  16.           'defaults' => array
  17.             'controller' => 'Application\Controller\User'
  18.             'action' => 'url'
  19.           ), 
  20.         ), 
  21.       ), 
  22.       // The following is a route to simplify getting started creating 
  23.       // new controllers and actions without needing to create a new 
  24.       // module. Simply drop new controllers in, and you can access them 
  25.       // using the path /application/:controller/:action 
  26.       'application' => array
  27.         'type' => 'Literal'
  28.         'options' => array
  29.           'route' => '/application'
  30.           'defaults' => array
  31.             '__NAMESPACE__' => 'Application\Controller'
  32.             'controller' => 'Index'
  33.             'action' => 'index'
  34.           ), 
  35.         ), 
  36.         'may_terminate' => true, 
  37.         'child_routes' => array
  38.           'default' => array
  39.             'type' => 'Segment'
  40.             'options' => array
  41.               'route' => '/[:controller[/:action]]'
  42.               'constraints' => array
  43.                 'controller' => '[a-zA-Z][a-zA-Z0-9_-]*'
  44.                 'action' => '[a-zA-Z][a-zA-Z0-9_-]*'
  45.               ), 
  46.               'defaults' => array
  47.               ), 
  48.             ), 
  49.           ), 
  50.         ), 
  51.       ), 
  52.       'user_list' => array
  53.         'type' => 'Segment'
  54.         'options' => array
  55.           'route' => '/user[/]'
  56.           'defaults' => array
  57.             '__NAMESPACE__' => 'Application\Controller'
  58.             'controller' => 'User'
  59.             'action' => 'index'
  60.           ), 
  61.         ), 
  62.         'may_terminate' => true, 
  63.         'child_routes' => array
  64.           'user' => array
  65.             'type' => 'Segment'
  66.             'options' => array
  67.               'route' => '[:name][/]'
  68.               'constraints' => array
  69.                 'name' => '[a-zA-Z0-9_-]+'
  70.               ), 
  71.               'defaults' => array
  72.                 'action' => 'show'
  73.               ), 
  74.             ), 
  75.             'may_terminate' => true, 
  76.             'child_routes' => array
  77.               'blog_list' => array
  78.                 'type' => 'Segment'
  79.                 'options' => array
  80.                   'route' => 'blog[/]'
  81.                   'constraints' => array
  82.                   ), 
  83.                   'defaults' => array
  84.                     'controller' => 'Blog'
  85.                     'action' => 'index'
  86.                   ) 
  87.                 ), 
  88.                 'may_terminate' => true, 
  89.                 'child_routes' => array
  90.                   'blog' => array
  91.                     'type' => 'Segment'
  92.                     'options' => array
  93.                       'route' => '[:blog_id]'
  94.                       'constraints' => array
  95.                         'blog_id' => '[0-9]+'
  96.                       ), 
  97.                       'defaults' => array
  98.                         'action' => 'show'
  99.                       ) 
  100.                     ), 
  101.                     'may_terminate' => true, 
  102.                   ), 
  103.                 ), 
  104.               ), 
  105.             ), 
  106.           ), 
  107.         ), 
  108.       ), 
  109.     ), 
  110.   ), 
  111.   'service_manager' => array
  112.     'abstract_factories' => array
  113.       'Zend\Cache\Service\StorageCacheAbstractServiceFactory'
  114.       'Zend\Log\LoggerAbstractServiceFactory'
  115.     ), 
  116.     'aliases' => array
  117.       'translator' => 'MvcTranslator'
  118.     ), 
  119.   ), 
  120.   'translator' => array
  121.     'locale' => 'en_US'
  122.     'translation_file_patterns' => array
  123.       array
  124.         'type' => 'gettext'
  125.         'base_dir' => __DIR__ . '/../language'
  126.         'pattern' => '%s.mo'
  127.       ), 
  128.     ), 
  129.   ), 
  130.   'controllers' => array
  131.     'invokables' => array
  132.       'Application\Controller\Index' => 'Application\Controller\IndexController'
  133.       'Application\Controller\User' => 'Application\Controller\UserController'
  134.       'Application\Controller\Blog' => 'Application\Controller\BlogController'
  135.     ), 
  136.   ), 
  137.   'view_manager' => array
  138.     'display_not_found_reason' => true, 
  139.     'display_exceptions' => true, 
  140.     'doctype' => 'HTML5'
  141.     'not_found_template' => 'error/404'
  142.     'exception_template' => 'error/index'
  143.     'template_map' => array
  144.       'layout/layout' => __DIR__ . '/../view/layout/layout.phtml'
  145.       'application/index/index' => __DIR__ . '/../view/application/index/index.phtml'
  146.       'error/404' => __DIR__ . '/../view/error/404.phtml'
  147.       'error/index' => __DIR__ . '/../view/error/index.phtml'
  148.     ), 
  149.     'template_path_stack' => array
  150.       __DIR__ . '/../view'
  151.     ), 
  152.   ), 
  153.   // Placeholder for console routes 
  154.   'console' => array
  155.     'router' => array
  156.       'routes' => array
  157.       ), 
  158.     ), 
  159.   ), 
  160. ); 
  161. ?> 

这个文件是骨架程序中自带的,我只是修改了router部分和controllers部分。要我写这么长的文件,那就太为难我了。这也是ZF官方发布了一个骨架程序的原因。

创建文件zf2\module\Application\src\Application\Controller\UserController.php:

  1. <?php 
  2. namespace Application\Controller; 
  3. use Zend\Mvc\Controller\AbstractActionController; 
  4. use Zend\View\Model\ViewModel; 
  5. class UserController extends AbstractActionController { 
  6.   public function urlAction() { 
  7.     $name = 'jing'
  8.     $blogId = 1; 
  9.     $urls = array
  10.       $this->url()->fromRoute('user_list'), 
  11.       $this->url()->fromRoute('user_list/user'array('name' => $name)), 
  12.       $this->url()->fromRoute('user_list/user/blog_list'array('name' => $name)), 
  13.       $this->url()->fromRoute('user_list/user/blog_list/blog'array('name' => $name'blog_id' => $blogId)), 
  14.     ); 
  15.     $view = new ViewModel(compact('urls')); 
  16.     $view->setTerminal(true); 
  17.     return $view
  18.   } 
  19.   public function indexAction() { 
  20.     $view = new ViewModel(); 
  21.     // 禁用布局模板 
  22.     $view->setTerminal(true); 
  23.     return $view
  24.   } 
  25.   public function showAction() { 
  26.     $username = $this->params()->fromRoute('name'); 
  27.     $view = new ViewModel(compact('username')); 
  28.     $view->setTerminal(true); 
  29.     return $view
  30.   } 
  31. ?> 

创建文件zf2\module\Application\src\Application\Controller\BlogController.php:

  1. <?php 
  2. namespace Application\Controller; 
  3. use Zend\Mvc\Controller\AbstractActionController; 
  4. use Zend\View\Model\ViewModel; 
  5. class BlogController extends AbstractActionController { 
  6.   public function indexAction() { 
  7.     $username = $this->params()->fromRoute('name'); 
  8.     $view = new ViewModel(compact('username')); 
  9.     $view->setTerminal(true); 
  10.     return $view
  11.   } 
  12.   public function showAction() { 
  13.     $username = $this->params()->fromRoute('name'); 
  14.     $blogId = $this->params()->fromRoute('blog_id'); 
  15.     $view = new ViewModel(compact('username''blogId')); 
  16.     $view->setTerminal(true); 
  17.     return $view
  18.   } 
  19. ?> 

zf2不支持Action参数绑定,ThinkPHP不仅支持绑定,还支持2种绑定方式:按变量名绑定和按变量顺序绑定。

zf2中Action必须得返回视图,除非exit()。如果你知道可以禁用视图的办法,请告诉我。

创建文件zf2\module\Application\view\application\user\url.phtml:

  1. <?php foreach ($urls as $url): ?> 
  2. <a href="<?php echo $url;?>"><?php echo $url;?><a/><br /> 
  3. <?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:

<?php echo $username; ?>的这篇博客的id为<?php echo $blogId; ?>

Yaf

安装Yaf

使用代码生成工具创建Yaf项目

修改启动文件yaf\application\Bootstrap.php,修改其中的_initRoute方法:

  1. $router = Yaf_Dispatcher::getInstance()->getRouter(); 
  2. $route0 = new Yaf_Route_Rewrite('url'array
  3.   'controller' => 'User'
  4.   'action' => 'url'
  5.     ), array() 
  6. ); 
  7. $route1 = new Yaf_Route_Rewrite('user'array
  8.   'controller' => 'User'
  9.   'action' => 'index'
  10.     ), array() 
  11. ); 
  12. $route2 = new Yaf_Route_Regex('#user/([a-zA-Z0-9_-]+)#'array
  13.   'controller' => 'User'
  14.   'action' => 'show'
  15.     ), array(1 => 'name',) 
  16. ); 
  17. $route3 = new Yaf_Route_Regex('#user/([a-zA-Z0-9_-]+)/blog#'array
  18.   'controller' => 'Blog'
  19.   'action' => 'index'
  20.     ), array(1 => 'name',) 
  21. ); 
  22. $route4 = new Yaf_Route_Regex('#user/([a-zA-Z0-9_-]+)/blog/([0-9]+)#'array
  23.   'controller' => 'Blog'
  24.   'action' => 'show'
  25.     ), array(1 => 'name', 2 => 'blogId',) 
  26. ); 
  27. $router->addRoute('url'$route0); 
  28. $router->addRoute('user_list'$route1); 
  29. $router->addRoute('user'$route2); 
  30. $router->addRoute("blog_list"$route3); 
  31. $router->addRoute("blog"$route4); 

Yaf有路由功能,但是没有根据路由名生成URL的方法。所以我定义了一个项目名,用于拼接URL。

在配置文件中添加配置项yaf\conf\application.ini:

project.name = 'yaf'

创建文件yaf\application\controllers\User.php:

  1. <?php 
  2. class UserController extends Yaf_Controller_Abstract { 
  3.   public function urlAction() { 
  4.     $name = 'jing'
  5.     $blogId = 1; 
  6.     $app = Yaf_Application::app(); 
  7.     $projectName = $app->getConfig()->project->name; 
  8.     $urls = array
  9.       "/{$projectName}/user"
  10.       "/{$projectName}/user/{$name}"
  11.       "/{$projectName}/user/{$name}/blog"
  12.       "/{$projectName}/user/{$name}/blog/{$blogId}"
  13.     ); 
  14.     foreach ($urls as $url) { 
  15.       echo "<a href=\"{$url}\">{$url}<a/><br />\n"
  16.     } 
  17.     return false; 
  18.   } 
  19.   public function indexAction() { 
  20.     echo '我是用户列表^_^'
  21.     // 禁用视图模板 
  22.     return false; 
  23.   } 
  24.   public function showAction($name) { 
  25.     echo "欢迎你,{$name}"
  26.     return false; 
  27.   } 

创建文件yaf\application\controllers\Blog.php:

  1. <?php 
  2. class BlogController extends Yaf_Controller_Abstract { 
  3.     public function indexAction($name) { 
  4.         echo "这是{$name}的博客列表"
  5.         return false; 
  6.     } 
  7.     public function showAction($blogId$name) { 
  8.         echo "{$name}的这篇博客的id为{$blogId}"
  9.         return false; 
  10.     } 

Yaf的Action支持参数绑定,是按变量名绑定的。$name、$blogId要和路由中配置的名称一样,而和参数顺序无关。

Laravel

新建Laravel项目:

composer create-project laravel/laravel --prefer-dist

清除合并文件。在目录laravel\vendor\下有个文件compiled.php,这个文件是为了减少IO提高框架性能,将很多类文件合并到一个文件中而生存的。在开发环境下,应该删除该文件,否则修改了一些文件发现没有效果,其实是因为文件已经合并缓存了。

清除命令:

php artisan clear-compiled

在生产环境中应该开启,以提升性能:

php artisan optimize --force

修改路由文件laravel\app\Http\routes.php:

  1. <?php 
  2. Route::get('/url'array('uses' => 'UserController@getUrl')); 
  3. Route::get('/user'array('uses' => 'UserController@getIndex')); 
  4. Route::get('/user/{username}'array('uses' => 'UserController@getShow')); 
  5. Route::get('/user/{username}/blog'array
  6.     'as' => 'blog_list'
  7.     'uses' => 'BlogController@getIndex'
  8. )); 
  9. Route::get('/user/{username}/blog/{blogId}'array
  10.     'as' => 'blog'
  11.     'uses' => 'BlogController@getShow'
  12. ))->where(array('blogId' => '[0-9]+')); 

查看路由定义情况:

php artisan route:list

输出:

  1. +--------+----------+-------------------------------+-----------+----------------------------------------------+------------+ 
  2. | Domain | Method   | URI                           | Name      | Action                                       | Middleware | 
  3. +--------+----------+-------------------------------+-----------+----------------------------------------------+------------+ 
  4. |        | GET|HEAD | url                           |           | App\Http\Controllers\UserController@getUrl   |            | 
  5. |        | GET|HEAD | user                          |           | App\Http\Controllers\UserController@getIndex |            | 
  6. |        | GET|HEAD | user/{username}               |           | App\Http\Controllers\UserController@getShow  |            | 
  7. |        | GET|HEAD | user/{username}/blog          | blog_list | App\Http\Controllers\BlogController@getIndex |            | 
  8. |        | GET|HEAD | user/{username}/blog/{blogId} | blog      | App\Http\Controllers\BlogController@getShow  |            | 
  9. +--------+----------+-------------------------------+-----------+----------------------------------------------+------------+ 

定义路由变量全局模式,修改文件laravel\app\Providers\RouteServiceProvider.php中的boot方法:

  1. public function boot(Router $router) { 
  2.     $router->pattern('username''[a-zA-Z0-9_-]+'); 
  3.     parent::boot($router); 

创建UserController控制器:

php artisan make:controller UserController

Laravel帮我们在laravel\app\Http\Controllers目录下创建了文件UserController.php,文件中已经为我们写好一部分骨架代码。修改文件laravel\app\Http\Controllers\UserController.php:

  1. <?php 
  2. namespace App\Http\Controllers; 
  3. use App\Http\Controllers\Controller; 
  4. class UserController extends Controller { 
  5.     public function getUrl() { 
  6.         $name = 'jing'
  7.         $blogId = 1; 
  8.         $urls = array
  9.             url('/user'), 
  10.             action('UserController@getShow'array($name)), 
  11.             route('blog_list'array($name)), 
  12.             route('blog'array($name$blogId)), 
  13.         ); 
  14.         foreach ($urls as $url) { 
  15.             echo "<a href=\"{$url}\">{$url}<a/><br />\n"
  16.         } 
  17.     } 
  18.     public function getIndex() { 
  19.         echo '我是用户列表^_^'
  20.     } 
  21.     public function getShow($name) { 
  22.         echo "欢迎你,{$name}"
  23.     } 

创建BlogController控制器:

php artisan make:controller BlogController

修改文件laravel\app\Http\Controllers\BlogController.php:

  1. <?php 
  2. namespace App\Http\Controllers; 
  3. use App\Http\Controllers\Controller; 
  4. class BlogController extends Controller { 
  5.     public function getIndex($name) { 
  6.         echo "这是{$name}的博客列表"
  7.     } 
  8.     public function getShow($name$blogId) { 
  9.         echo "{$name}的这篇博客的id为{$blogId}"
  10.     } 

Laravel的Action也支持参数绑定,是按变量顺序绑定的,和变量名无关。

后语

我是Laravel粉,但是我也没有想黑其他框架的意思,大家有兴趣也可以用自己熟悉的框架来实现这个小例子,写了记得@我,语言不限。

以上所述就是本文的全部内容了,希望大家能够喜欢。

Tags: ZF2 Yaf Laravel

分享到: