侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

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

Laravel  /  管理员 发布于 8年前   196

前言

读过一篇关于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:

 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:

\n";    }  }  public function index() {    echo '我是用户列表^_^';  }  public function show($name) {    echo "欢迎你,{$name}";  }}?>

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

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

输出:

复制代码 代码如下:

/tp/user

/tp/user/jing

/tp/user/jing/blog

/tp/user/jing/blog/1

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

 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:

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:

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:


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

我是用户列表^_^
创建文件zf2\module\Application\view\application\user\show.phtml:

欢迎你,
创建文件zf2\module\Application\view\application\blog\index.phtml:

这是的博客列表
创建文件zf2\module\Application\view\application\blog\show.phtml:

复制代码 代码如下:

的这篇博客的id为

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:

getConfig()->project->name;    $urls = array(      "/{$projectName}/user",      "/{$projectName}/user/{$name}",      "/{$projectName}/user/{$name}/blog",      "/{$projectName}/user/{$name}/blog/{$blogId}",    );    foreach ($urls as $url) {      echo "{$url}
\n"; } return false; } public function indexAction() { echo '我是用户列表^_^'; // 禁用视图模板 return false; } public function showAction($name) { echo "欢迎你,{$name}"; return false; }}

创建文件yaf\application\controllers\Blog.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:

复制代码 代码如下:

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:

复制代码 代码如下:

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 "{$url}
\n";
        }
    }
    public function getIndex() {
        echo '我是用户列表^_^';
    }
    public function getShow($name) {
        echo "欢迎你,{$name}";
    }
}

创建BlogController控制器:

复制代码 代码如下:

php artisan make:controller BlogController

修改文件laravel\app\Http\Controllers\BlogController.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粉,但是我也没有想黑其他框架的意思,大家有兴趣也可以用自己熟悉的框架来实现这个小例子,写了记得@我,语言不限。

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

请您花一点时间将文章分享给您的朋友或者留下评论。我们将会由衷感谢您的支持!

您可能感兴趣的文章:

  • thinkphp5 URL和路由的功能详解与实例
  • thinkPHP5.1框架路由::get、post请求简单用法示例
  • thinkphp的URL路由规则与配置实例
  • ThinkPHP路由详解
  • thinkphp路由规则使用示例详解和伪静态功能实现(apache重写)
  • 改写ThinkPHP的U方法使其路由下分页正常
  • thinkphp中U方法按路由规则生成url的方法
  • ThinkPHP路由机制简介
  • thinkPHP5框架路由常用知识点汇总


  • 上一条:
    解决ThinkPHP关闭调试模式时报错的问题汇总
    下一条:
    THINKPHP支持YAML配置文件的设置方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • Laravel 11.14版本发布 - 新的字符串助手和ServeCommand改进(0个评论)
    • Laravel 11.12版本发布 - Artisan的`make`命令自动剪切`.php `扩展(0个评论)
    • Laravel的轻量型购物车扩展包:binafy/laravel-cart(0个评论)
    • Laravel 11.11版本发布 - 查看模型中的第三方关系:show(0个评论)
    • 近期文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-07
    • 2017-08
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2020-10
    • 2020-11
    • 2021-01
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客