V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iloveyou
V2EX  ›  PHP

Laravel 每个控制器都需要写个路由,蛋疼

  •  1
     
  •   iloveyou · 2016-04-19 18:55:51 +08:00 · 25647 次点击
    这是一个创建于 3174 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用过 ci 、 yii ,都有默认的路由,基本上都是 module-controller-action ,思路走到哪,代码写到哪,非常流畅。文件组织的过程顺便把 seo 考虑进去了,只有特殊的 seo 需求才会专门订制路由。

    如果每个 controller 都需要建个 route 那 controller 还有啥存在意义,都用闭包解决算了,或者路由里直接调 business 逻辑。

    当然这样设计必然有其优越之处,不过编码也要考虑“爽脆度”,写起来不爽,用起来不干脆,我是适应不了。
    54 条回复    2020-08-27 16:40:07 +08:00
    Bantes
        1
    Bantes  
       2016-04-19 19:03:24 +08:00
    我是首先写 migration ,然后写 model ,然后写路由,最后写 controller 。感觉没什么啊,难道是我太菜了...
    wclssdn
        2
    wclssdn  
       2016-04-19 19:16:06 +08:00   ❤️ 1
    之前看过某人的 laravel 路由执行时间就是几十毫秒。。。
    mcfog
        3
    mcfog  
       2016-04-19 19:19:05 +08:00   ❤️ 2
    真想要的话, glob 一下目录目录自动注册路由,或者在路由 miss 的地方重新按照你希望的规则找一下是否存在对应的 action 调用一下,代码写一写估计也就一百多行╮(╯▽╰)╭ 和你写这个帖子然后看回帖的时间差不了多少

    至于为啥不自带这类功能,是因为 url 和类名方法名耦合就是一条不归路,有了所谓 module controller action 你会发现你想要 submodule 想要 default action 想要各种例外,然后就呵呵了。今天省了 10 秒钟定义路由的时间,下次 url 重新规划的时候就呵呵了
    yuxing1171
        4
    yuxing1171  
       2016-04-19 19:30:22 +08:00
    laravel 这种给你很大的自由, 况且定义路由也花不了多少时间。
    zonghua
        5
    zonghua  
       2016-04-19 19:38:49 +08:00
    Django 还提供了视图反向生成 url 的方法呢。
    msg7086
        6
    msg7086  
       2016-04-19 20:20:12 +08:00   ❤️ 15
    可能是继承自 Rails 的思想吧。
    Rails 里以前也见过人用泛路由匹配,结果程序写了几万行以后特么根本不知道自己的程序对外暴露了多少接口出去。
    回头整理和重构的时候那真叫一个吐血。 Controller 里的方法都不敢乱删,否则一不小心就 break 了外部调用。

    自动路由一时爽,代码全家火葬场啊。
    xujif
        7
    xujif  
       2016-04-19 20:30:32 +08:00 via iPhone
    Router::pattern('path','.+')
    Router::any('{path}',function($path){
    //自己分割路径转发吧, Controller::call()
    })
    你看,默认路由不就几句话的事情吗
    ps 手机打的,可能有点小问题,
    ykjsw
        8
    ykjsw  
       2016-04-19 20:31:35 +08:00
    @wclssdn 几十毫秒很慢了。。。
    kankana
        9
    kankana  
       2016-04-19 20:33:50 +08:00
    `Route::controller` 和 `Route::resource` 不能满足?

    不过,话说回来, 听楼上的话,千万别用自动路由...

    看下这篇文章 https://philsturgeon.uk/php/2013/07/23/beware-the-route-to-evil/
    xuwenmang
        10
    xuwenmang  
       2016-04-19 20:42:48 +08:00
    听说 5.0 的时候已经删了,不过正式版又加上了
    msg7086
        11
    msg7086  
       2016-04-19 20:50:44 +08:00
    换句话说,自动路由适合小规模随便耍耍,手动路由适合大型项目开发。
    大型项目用自动路由分分钟崩掉程序员。
    iloveyou
        12
    iloveyou  
    OP
       2016-04-19 20:55:01 +08:00
    @msg7086 有道理
    killall
        13
    killall  
       2016-04-19 21:42:07 +08:00 via Android
    @msg7086 感觉正好相反啊,对于几百个页面的项目,如果不想办法做通用路由,每个控制器都要反复配一次,绝对是噩梦,还有在写路由的时候还得查一遍自己写的路由别人写没写过,再碰上正则的路由还得分析一遍,再碰上分组开发…不用自动路由绝对是噩梦…
    changwei
        14
    changwei  
       2016-04-19 23:54:43 +08:00 via Android
    @killall 有道理啊,开发时候先做测试,做完之后再一个一个配置路由也好啊
    levn
        15
    levn  
       2016-04-20 00:01:56 +08:00 via Android
    不是传说中组件都可以替换的高级东东么
    orvice
        16
    orvice  
       2016-04-20 00:12:31 +08:00
    laravel 也有自动路由,不知道最新版还有吗。

    不过写路由真的很好!现在看公司一些以前的 yii 的东西,都木有写路由别人看起来真的蛋疼。
    killall
        17
    killall  
       2016-04-20 00:55:22 +08:00 via Android
    @changwei 集团军 作战,这种配置除非每个组有独特的明名空间,否则不敢想象
    chaegumi
        18
    chaegumi  
       2016-04-20 07:57:33 +08:00
    企业自己的项目写固定的还好,如果是 cms 给客户的就得写分发了
    msg7086
        19
    msg7086  
       2016-04-20 08:11:50 +08:00
    @killall 几百个页面的项目我觉得是时候考虑拆分 Microservice 了。
    WildCat
        20
    WildCat  
       2016-04-20 08:13:26 +08:00 via iPhone
    自动路由用 ThinkPHP 啊, XD
    zaishanfeng
        21
    zaishanfeng  
       2016-04-20 08:28:17 +08:00 via Android
    如此优雅的路由方式 看来卤煮适合 tp 快去用吧
    killall
        22
    killall  
       2016-04-20 08:41:26 +08:00 via iPhone
    @msg7086 microservice 同样面临 api 多的要命的情况
    zztao
        23
    zztao  
       2016-04-20 09:07:19 +08:00
    学习 servlet 要 mapper
    cai314494687
        24
    cai314494687  
       2016-04-20 09:24:07 +08:00
    还是 Yii2 好
    Liang
        25
    Liang  
       2016-04-20 09:51:41 +08:00
    route::controller('/', 'XXXController');

    然后在 XXXController 实现你所有功能。

    我是不是很聪明?
    msg7086
        26
    msg7086  
       2016-04-20 10:03:28 +08:00
    @killall 合理拆分以后会好很多。
    再怎么多得要命,总比拿到手发现就一句 match ":controller/:action/:id" 然后慢慢去翻几十个 Controller 来得好吧。
    tinkerer
        27
    tinkerer  
       2016-04-20 10:21:02 +08:00 via Android
    tinkerer
        28
    tinkerer  
       2016-04-20 10:21:30 +08:00 via Android
    司禁止用自动路由模板
    kchum
        29
    kchum  
       2016-04-20 10:23:08 +08:00
    这样可以知道有多少页面和 api 暴露出去。
    好管理。
    icybee
        30
    icybee  
       2016-04-20 10:26:25 +08:00
    所以说 laravel 是轻量级框架。。。
    LukeXuan
        31
    LukeXuan  
       2016-04-20 11:00:25 +08:00 via Android
    写 controller 的时候用 annotation 添加路由就好了… symfony+doctrine 有一个解决方案的
    gearh
        32
    gearh  
       2016-04-20 11:13:56 +08:00
    解耦,像「 url 」 - 「控制器」,或者类似的「表单 」- 「变量」 - 「数据库」,先不考虑安全问题,像这种直肠子的设计,刚开始开发的时候爽,但是未来业务复杂了是要吃瘪的。
    500miles
        33
    500miles  
       2016-04-20 11:54:00 +08:00
    自动路由 : 约定 > 配置

    自定义路由 : 配置 > 约定


    设计理念不同 ......
    yrdr
        34
    yrdr  
       2016-04-20 12:19:36 +08:00
    这是方便而不是繁琐,你做好路由分层,一样会很快
    Felldeadbird
        35
    Felldeadbird  
       2016-04-20 15:14:35 +08:00
    对于懒人肯定是 CI,YII,TP 这些舒服。其实思维转变需要一个过程。所以我一直没用 laravel 。
    LINAICAI
        36
    LINAICAI  
       2016-04-20 15:47:40 +08:00
    卧槽,这都有人吐槽
    lygmqkl
        37
    lygmqkl  
       2016-04-20 23:45:28 +08:00 via iPhone
    @msg7086 想请教你几个问题
    第一 开发的内容不做对应文档说明吗?没有质量控,版本控制和测试吗?
    第二 路由 seo 这些不是项目初期就应该定下来的吗?看你的意思是几万行的项目要出 20-30 种路由规则
    第三 即使项目足够复杂,不应该考虑拆分吗?
    第四 你所谓的 controller 自定义路由模式真的适合大团队开发的项目吗?感觉像参差不齐的外包团队,自己搞自己的完全不考虑别人。
    最后想说,如有冒犯请多担待。有些话说出来是要负责的,你今天说的很多话可能会影响到很多人。
    会用一个框架不是你说别的思想错的资本,同样是 PHPer 有人拿 5w 一个月有人拿 5000 人和人不一样罢了
    lygmqkl
        38
    lygmqkl  
       2016-04-20 23:47:45 +08:00 via iPhone
    @killall 为你点个赞 总算有做过团队开发的出个声,团队开发中的问题不是有些人想想就能想到的。
    denghongcai
        39
    denghongcai  
       2016-04-21 03:28:58 +08:00
    @lygmqkl 不要这么激动,想想把你说的几个问题来问自动路由不也能成立?
    团队的好恶决定是用什么样的模式来做,显式路由清晰,看着 URL 不用去猜,配合 IDE 易查找;隐式路由方便,在有的框架下还能和文件结构一一对应,在注释完善的情况下也不至于说真的乱到哪里去(当然加了注释的话和自动路由其实没什么区别)
    说 Laravel 的性能呢,主要还是在框架启动速度上比较慢, swoole 套层壳还是可以接受的,除开启动速度,其他方面的性能和别的框架没有数量级的差别,路由判断也没有前几层楼说的几十毫秒- -
    ango
        40
    ango  
       2016-04-21 09:59:25 +08:00
    @lygmqkl 确实,就现阶段我所经历的都是团队约定好路由层规则再开发(多个 Microservice ),要不然项目 URI 规则就被按每个人的想法来跑飞了,哪怕是选用 Laravel ,路由自定义配置也是按约定规则来个人配置(这个时候普遍反应都是多此一举,干嘛不直接 URI 映射 /显式路由)。
    所以有时候也会有如同 LZ 一样的困惑……看了一下楼上各位的回复,对于 LZ 的困惑我觉得它依然存在……
    msg7086
        41
    msg7086  
       2016-04-21 11:00:20 +08:00
    @lygmqkl 你说的都没错。
    我对我自己说的话负责任,但是没法对别人因为我说的话产生的影响而负责任。
    毕竟这里是讨论区,我觉得有互相不同的观点才是正常的。
    那么我们就来看看你提到的这几点吧。
    1. 文档,质量控制,版本控制,测试。
    是的,是应该有这些。但是偏偏我司的系统就是没有。
    去年来了个新员工, Ruby 老手,进来以后花了几个月时间分析和优化系统。
    后来在各种注释里留下不少对之前员工的脏话后愤而辞职了。
    如果你的系统这几点都能做好,当然不成问题。
    但是不是所有的公司都能做到这样。就说自动路由,你能保证你对外暴露的接口都能完整地整理在文档里吗?
    俗话说得好,代码才是最好的注释。显式申明你用到的路由本身就是一个精确反映实际的文档。
    2. 路由在项目初期就定下来。
    你开玩笑的吧,一个要做几年的项目的路由能一开始就定下来?
    我们现在的系统就是 50k 行代码,前后写了七八年,经手的程序员几十人。
    路由就是我 26 楼写的自动路由,前端界面往后端调用的时候直接 Call 到 Controller 上的方法。
    (实际情况其实比这个还复杂点,但是和本题无关所以就不提了。如果想知道我可以再说下去。)
    然而我们根本不知道前端到底用到了哪些后端方法。
    所以每次动控制器的时候根本不知道哪些方法是前端会用到的,哪些是可以随便改动的。
    3. 大项目拆分。
    这个没错。但是有几个问题。
    大项目不可能无限分割成微型项目。所以不可避免的有些项目还是有数千甚至上万行。
    如果全部用自动路由,你还是得到处搜索函数名,确保没有奇怪的地方调用到你的函数,才可以改动结构。
    除非你把所有的代码都从控制器里剥离出去,放在 Service 或者 Model 里。
    然而这样的话控制器就成了实质性的路由文档了。
    (并没什么不可以,如果架构师和程序员都靠谱的话,这样其实是不错的。)
    (但是你并不总是能遇到靠谱的同事。)
    4. 不知道你说的是什么。 26 楼的话,那个就是自动路由了。

    最后说下利益相关吧。 PHP 从初中开始玩,那时候还只有 PHP4.x ,还没到谈框架的年代。后来 PHP5 了自己写了个框架,工作以后送给公司用了,后来成了公司的核心框架,虽然并没什么亮点。现在写 Rails ,在一个五六人的团队里一起做一个 8 年多的 Rails 1.x 项目,大概有 50k 行的量,虽然基本都是辣鸡。现代 PHP 我已经不会写了,弃掉 PHP 的时候 Composer 才刚刚出来,所以对 Laravel 了解不多,不确定显式路由是不是有坑,不过至少 Rails 里显式路由的规则数量我还是可以接受的。上文大多以 Rails 的角度来谈路由,如果 Laravel 有不同之处还请提出来。
    谢谢。
    lygmqkl
        42
    lygmqkl  
       2016-04-21 11:25:40 +08:00
    @msg7086 既然你没在写 php 那就没啥好说的了,可能我们所处的团队和理念差别较大,国内有很多夸夸其谈的人,代码不怎么样,但是说起来一套一套的,到实际项目就蔫了。

    可能给你了不太好的感觉,抱歉。
    lygmqkl
        43
    lygmqkl  
       2016-04-21 11:27:37 +08:00
    @ango 我和你的想法差不多,我思量了一下,国内还是在前期规划性稍微投入的少了一些导致的, 前期架构 SEO 这些东西都设置好,后面慢慢变。。。。。真的想想都要抓狂。
    msg7086
        44
    msg7086  
       2016-04-21 11:35:48 +08:00
    @lygmqkl 很多时候的很多做法其实是妥协的结果。
    如果什么事情都能找到最理想的员工用最理想的办法去做,当然什么都好说。
    但是团队就是团队,就会遇上一些奇妙的事情。
    比如因为没钱所以招不了大牛,因为要抢占市场所以赶着开发,遇上留下了各种技术债什么的。
    自动路由大概就是技术债的一种吧。
    还债方法要么用显式路由,要么就如你说的,合理拆分,详细归档。
    PS: 国内情况我也不清楚,不过哪里都有你说的这种人,应该也不限定于国内的。
    msg7086
        45
    msg7086  
       2016-04-21 11:36:53 +08:00
    @msg7086 s/遇上 /于是 /
    raywill
        46
    raywill  
       2016-08-16 15:12:36 +08:00
    也可以不这么玩。 Laravel 并没有要求你一定这么做,只不过大家都按照官方的建议逐步形成了这一 best Practice 而已。

    不按照官方的玩法,怎么做呢?理论上可以这么做:

    route.php 里面只写一个路由:
    ```
    Route::any('/', function() {
    // 自己写一段解析 queryString 的代码,然后根据参数调用对应的 Controller
    });
    ```

    不过,你就损失了 router middleware , group routing 等等好处。一切自己动手。


    更进一步地,你还可以自己重写 Routing 接口,完整实现自己的一套 Routing 方法。
    wyan453351466
        47
    wyan453351466  
       2017-01-11 10:27:15 +08:00
    @msg7086 抱歉不能同意你的说法。“程序写了几万行以后特么根本不知道自己的程序对外暴露了多少接口出去”。问题是就算你手动路由,当路由配置写了几千行的时候 你特么也没法判断自己对外暴露了多少接口啊!! 几千行的配置!你怎么看!更乱好吗?!

    还不如自动路由,遍历一下所有控制器的方法就知道有多少接口了啊!你不想暴露的接口可以单独写在一个模块里啊!
    baoguok
        48
    baoguok  
       2017-01-11 10:31:53 +08:00
    框架应该支持自动路由和显式自定义路由,这样更灵活。

    我司目前使用的是自动路由,暂时没有发现什么坑,功能页面 200 个以上。

    此外,管理系统和接口对路由的要求不一样。管理系统那么自动路由就非常爽,但是 api 接口那么就需要显式自定义路由+自动路由。
    elvba
        49
    elvba  
       2017-01-11 11:06:14 +08:00
    @wyan453351466
    `php artisan route:list` 就能看到注册了哪些路由了
    也可以用 `Route::getRoutes()` 拿到所有路由信息,然后你想怎么展示就怎么展示
    wyan453351466
        50
    wyan453351466  
       2017-01-11 11:43:59 +08:00
    @elvba 嗯,感谢你的回复。我的意思是。为什么不能两者兼有呢?换句话说,为什么 laravel 不鼓励隐式路由的使用?

    毕竟对于我来说,就算用显式路由,我也是按照一个统一的规则(模块 /控制器 /方法),重复的去写啊。。 那为嘛不直接给我自动匹配了。

    刚才我反驳 @msg7086 所说的,隐式路由会导致不知道暴露了多少接口出去。我相信也可以匹配出来的啊。实现难度可能比匹配显式路由更低。
    msg7086
        51
    msg7086  
       2017-01-12 01:07:22 +08:00
    @wyan453351466 看了一眼发帖时间。

    显式路由是你从外部用到某个控制器方法的时候才手动加入,而隐式路由那是阿猫阿狗看到有这个控制器方法就直接怼进前端里了。

    你说的这些我们都懂, Rails 也有 resources 方法可以自动生成 restful 的标准路由,一行代码解决一个 model ,如果你完全遵照统一规则来写的话,直接用 resources 就能解决了,不需要一个路由一行的。
    问题是大多数时候,都是辣鸡程序员开坑,倒霉程序员跳坑,这种时候显式比隐式带来的麻烦少得多。
    elvba
        52
    elvba  
       2017-01-13 14:21:54 +08:00
    @wyan453351466
    显示路由的最大好处是自由灵活,不受限制
    隐式路由你需要去看文档或者看源码才知道它的匹配规则是怎样的,显示则不用
    举个例子:两个不同的路由,调用同一个控制器里的方法 A ,如果是隐式路由就要再多写一个方法 B ,然后这个方法 B 再去调用方法 A ,显示路由增加一条路由规则即可,不会涉及到控制器的修改。这种场景可能不多,但肯定会有。
    nextvay
        53
    nextvay  
       2018-09-03 12:19:45 +08:00
    C603H6r18Q1mSP9N
        54
    C603H6r18Q1mSP9N  
       2020-08-27 16:40:07 +08:00
    //from files or db,建议后台使用
    $routes = [
    ['path'=>'/java', 'controller'=>'MovieController']
    ];
    foreach($routes as $router) {
    Route::resource($router['path'],$router['controller']);
    }

    //建议前台 /api 使用
    Route::any('/{dir}/{module}/{action}', function ($dir, $module, $action,Router $router) {
    return app()->call('App\\'.ucfirst($dir).'\\Controllers\\' . ucfirst($module) . 'Controller' .'@'.$action);
    });

    看看香不香
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2607 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 10:25 · PVG 18:25 · LAX 02:25 · JFK 05:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.