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对应用户的一篇博客文章
方案引用自原文:
- '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项目:
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:
- <?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}";
- }
- }
- ?>
访问:http://127.0.0.1/tp/url
输出:
- <a href="/tp/user">/tp/user<a/><br />
- <a href="/tp/user/jing">/tp/user/jing<a/><br />
- <a href="/tp/user/jing/blog">/tp/user/jing/blog<a/><br />
- <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:
- <?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:
<?php echo $username; ?>的这篇博客的id为<?php echo $blogId; ?>
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:
project.name = 'yaf'
创建文件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:
- <?php
- class BlogController extends Yaf_Controller_Abstract {
- public function indexAction($name) {
- echo "这是{$name}的博客列表";
- return false;
- }
- public function showAction($blogId, $name) {
- echo "{$name}的这篇博客的id为{$blogId}";
- return false;
- }
- }
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:
- <?php
- Route::get('/url', array('uses' => 'UserController@getUrl'));
- Route::get('/user', array('uses' => 'UserController@getIndex'));
- Route::get('/user/{username}', array('uses' => 'UserController@getShow'));
- Route::get('/user/{username}/blog', array(
- 'as' => 'blog_list',
- 'uses' => 'BlogController@getIndex',
- ));
- Route::get('/user/{username}/blog/{blogId}', array(
- 'as' => 'blog',
- 'uses' => 'BlogController@getShow',
- ))->where(array('blogId' => '[0-9]+'));
查看路由定义情况:
php artisan route:list
输出:
- +--------+----------+-------------------------------+-----------+----------------------------------------------+------------+
- | Domain | Method | URI | Name | Action | Middleware |
- +--------+----------+-------------------------------+-----------+----------------------------------------------+------------+
- | | GET|HEAD | url | | App\Http\Controllers\UserController@getUrl | |
- | | GET|HEAD | user | | App\Http\Controllers\UserController@getIndex | |
- | | GET|HEAD | user/{username} | | App\Http\Controllers\UserController@getShow | |
- | | GET|HEAD | user/{username}/blog | blog_list | App\Http\Controllers\BlogController@getIndex | |
- | | GET|HEAD | user/{username}/blog/{blogId} | blog | App\Http\Controllers\BlogController@getShow | |
- +--------+----------+-------------------------------+-----------+----------------------------------------------+------------+
定义路由变量全局模式,修改文件laravel\app\Providers\RouteServiceProvider.php中的boot方法:
- public function boot(Router $router) {
- $router->pattern('username', '[a-zA-Z0-9_-]+');
- parent::boot($router);
- }
创建UserController控制器:
php artisan make:controller UserController
Laravel帮我们在laravel\app\Http\Controllers目录下创建了文件UserController.php,文件中已经为我们写好一部分骨架代码。修改文件laravel\app\Http\Controllers\UserController.php:
- <?php
- namespace App\Http\Controllers;
- use App\Http\Controllers\Controller;
- class UserController extends Controller {
- public function getUrl() {
- $name = 'jing';
- $blogId = 1;
- $urls = array(
- url('/user'),
- action('UserController@getShow', array($name)),
- route('blog_list', array($name)),
- route('blog', array($name, $blogId)),
- );
- foreach ($urls as $url) {
- echo "<a href=\"{$url}\">{$url}<a/><br />\n";
- }
- }
- public function getIndex() {
- echo '我是用户列表^_^';
- }
- public function getShow($name) {
- echo "欢迎你,{$name}";
- }
- }
创建BlogController控制器:
php artisan make:controller BlogController
修改文件laravel\app\Http\Controllers\BlogController.php:
- <?php
- namespace App\Http\Controllers;
- use App\Http\Controllers\Controller;
- class BlogController extends Controller {
- public function getIndex($name) {
- echo "这是{$name}的博客列表";
- }
- public function getShow($name, $blogId) {
- echo "{$name}的这篇博客的id为{$blogId}";
- }
- }
Laravel的Action也支持参数绑定,是按变量顺序绑定的,和变量名无关。
后语
我是Laravel粉,但是我也没有想黑其他框架的意思,大家有兴趣也可以用自己熟悉的框架来实现这个小例子,写了记得@我,语言不限。
以上所述就是本文的全部内容了,希望大家能够喜欢。
Tags: ZF2 Yaf Laravel
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)