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

[吐槽]刚读了 yii3-demo, PHP 框架是怎么把 PHP (优雅的)玩死的。

  •  1
     
  •   dvaknheo · 2020-04-13 16:30:36 +08:00 · 15986 次点击
    这是一个创建于 1471 天前的主题,其中的信息可能已经有所发展或是发生改变。
    虽然是看 yii3-demo 吐槽的,但 Laravel 等框架也适用。

    业务代码里,和框架相关的代码越少才是耦合性越低啊。口口声声说解耦,但是一看代码里一堆和框架代码相关的,这能叫解耦么。

    业务代码里,框架相关的代码多,意味着碰到框架相关的代码就越多

    读代码,最怕的之一是:这东西怎么来的。 一两个特例马上能教人懂,多了没法马上会啊。

    View 里不能做任何计算,不能 include 非 View 的代码。

    Laravel 优雅的带着 PHP 优雅的 Java 化。当初 PHP 上手就干的年代,这是 PHP 的优势。

    现在一堆代码,业务相关的没几行,这还是 PHP 么。

    ORM 就非用不可么,Data struct 不容易理解么

    有好用的文件路由不用,非得手写路由 (src/Factory/AppRouterFactory.php)
    PHPer 的原则应该是 其他路由模式是文件路由的补充啊。

    配置文件里一堆 use (config/web.php)

    MVC 缺层都是大家的共识了, 业务逻辑层叫 Service 或 Logic 我都无所谓,但直接 Controller 里调用 ORM,以前 10k 行的 Controller 啊。 从 Controller 里把业务逻辑剥离出来,跑命令行测试不好么。

    PHP 开发速度很快,运行速度也很快。 没必要为了那些优雅牺牲开发速度,运行速度。

    讲真,我动力再足一点,写个同功能的 插进这些框架的 demo 中, 让大家见识一下应该用什么样的手段最符合 PHP 的快速开发模式。
    126 条回复    2020-05-06 23:33:44 +08:00
    1  2  
    stevenhawking
        1
    stevenhawking  
       2020-04-13 16:43:07 +08:00
    赞同, Yii 已经过了流行的年代了;
    qq1340691923
        2
    qq1340691923  
       2020-04-13 16:43:51 +08:00
    多人合作
    jhdxr
        3
    jhdxr  
       2020-04-13 16:49:42 +08:00
    > ORM 就非用不可么,Data struct 不容易理解么
    我寻思应该没有哪个框架能够拦着你用 PDO 吧?

    > 有好用的文件路由不用,非得手写路由
    单入口和多入口这两者的战争也得十年以上的历史了吧,但现在基本上都是单入口了。

    > 但直接 Controller 里调用 ORM
    没看过 yii3-demo,但是在 laravel 里至少这么做并没有被推荐?我印象中看过的大部分都还是会分一个 repository 出来
    onion83
        4
    onion83  
       2020-04-13 16:54:04 +08:00   ❤️ 6
    应该说 PHP 社区的节奏被 Java 那群人带坏了
    firefox12
        5
    firefox12  
       2020-04-13 17:02:53 +08:00   ❤️ 2
    大人 时代变了, 这些已经被认为是必须的, 只能说 php 没有拿出好的解决方案来适应需求的变化。

    刚开始玩 php 的时候 还是 4.0 时代, 那时候 主机可能只有 512M 内存,要跑 mysql php apache, php 简单灵活 面向过程是非常棒的。java? 不过是慢而笨重的代名词。现在普通主机也有 8G 内存, 慢 卡, 内存小已经不是 JAVA 的瓶颈,JAVA 开发规范 面向接口 这些优势被快速放大,所以 Php 没有新的东西 只能面对 模式上比不过 Java,用的人越来越少的情景。
    lepig
        6
    lepig  
       2020-04-13 17:12:10 +08:00   ❤️ 3
    上手就干的年代 已经过去了。不整点花 怎么涨工资
    HiCode
        7
    HiCode  
       2020-04-13 17:12:11 +08:00   ❤️ 4
    昨天的吐槽:

    1 、PHP 从一开始流行就是因为适合小型项目,开发效率及运行效率都不错;

    2 、PHP 大流行后,部分有追求的程序员希望给 PHP 加一点 B 格,开始用各种模式要求 PHP,让 PHP 往 Java 方向发展。但 PHP 是脚本语言,Java 不是,Java 本身有足够的性能可以支撑起各种设计模式的性能损耗(但还是经常被吐槽太重太慢)——而 PHP 并没有这个性能来支撑。

    3 、各类设计模式在 PHP 项目中的普及,确实提高了效率,增强了一丢丢的团队协作,但开发的复杂性和性能的损耗却让 PHP 失去了他最开始的拥趸。

    4 、为了追求性能和模式,所谓高手们抛下了 PHP 改用 go 、java 、c#,留下一个所谓“优雅”的 PHP 开发氛围。


    最近在优化自己框架的时候,在“性能”和“优雅”之间产生了疑惑,思考后有了上面的吐槽。

    如果是打工,选择一个优雅的框架让自己写的爽——是非常有必要的,毕竟服务器成本是老板出的,钱能搞定的问题就不是问题。

    如果是服务器钱要自己出,那就要好好考虑了。

    我选择性能。
    dvaknheo
        8
    dvaknheo  
    OP
       2020-04-13 17:26:50 +08:00
    @jhdxr
    没看过 yii3-demo,但是在 laravel 里至少这么做并没有被推荐?我印象中看过的大部分都还是会分一个 repository 出来

    Controller 里调用的就应该是业务逻辑的结果, 不管什么 repository 还是 orm 的东西。 我们要的就是一次调用得到的结果。

    一个业务逻辑,可能要由 多个 repository 完成。 得到的 结果数组,输出给 view 。view 里基本不做计算。 因为 view 也得由 php 程序员来改,smarty 这类的模板,还是得由 php 程序员来改。没必要那么折腾。
    weirdo
        9
    weirdo  
       2020-04-13 18:03:41 +08:00   ❤️ 2
    楼主加油,快让我们见识一下应该用什么样的手段最符合 PHP 的快速开发模式。 [绝对没有阴阳怪气!
    wangyzj
        10
    wangyzj  
       2020-04-13 20:43:51 +08:00
    上手就干
    所以我还在用 tp3 和 yii2
    ipwx
        11
    ipwx  
       2020-04-13 20:48:17 +08:00   ❤️ 9
    楼主的思维,和 jQuery 一把梭的老人,我觉得都差不多。
    Takamine
        12
    Takamine  
       2020-04-14 00:13:27 +08:00 via Android
    P++正在路上。 :doge:
    ywisax
        13
    ywisax  
       2020-04-14 01:22:37 +08:00   ❤️ 1
    这种事情,要看业务复杂度的。单纯跑个 demo 就来批评前辈很不妥当。

    另外,一个很明显的趋势就是 web 业务复杂度正在不断提升,所以 PHP 社区更加关注的是怎么降低业务复杂度,提高代码复用,Java 社区就是个很好的参考。

    所以,Lara/Yii2 的做法一点都没问题。Lara 的 Facade 、Yii2 的 Components 都是好的设计。组建起他们的各个组件,如 symfony 家族、codeception 等等工具,都是很值得去琢磨的东西。
    luckyrayyy
        14
    luckyrayyy  
       2020-04-14 01:51:47 +08:00 via iPhone
    为什么我想到了 thinkphp 挺合适
    king888
        15
    king888  
       2020-04-14 08:15:30 +08:00
    思维要转变下,通过产品为导向,没必要计较这些事情,所有产品前期重点都不是考虑这些事情上面的,优雅不优雅,跟你产品运营,融资关系不大,只有小步快跑迭代,才能在所有竞争者中冲出重围,钱到位,什么技术栈,什么技术架构,不是水到渠来的事情
    lp7631010
        16
    lp7631010  
       2020-04-14 08:35:39 +08:00
    看到你这么讲 突然有点理解前端工程师为什么折腾那么多花里胡哨的前端框架出来了,讲道理,那些花里胡哨的前端框架是不是比 jquery 有很大的进步,就像你拿现代的 php 框架和上古时期的 php 写法比差不多
    cooooler
        17
    cooooler  
       2020-04-14 08:40:37 +08:00
    拿落后当先进?
    MeteorCat
        18
    MeteorCat  
       2020-04-14 08:52:15 +08:00 via Android
    当年鸟哥也吐槽这个问题,很多框架越来越冗余
    zjsxwc
        19
    zjsxwc  
       2020-04-14 08:52:43 +08:00   ❤️ 1
    PHP 论框架设计的好,低耦合,还得是 symfony,那么多框架、那么多三方库都是基于 symfony,毫无疑问是 php 生态的基石
    neroransom
        20
    neroransom  
       2020-04-14 09:09:27 +08:00 via Android
    的地得要用对
    Varobjs
        21
    Varobjs  
       2020-04-14 09:56:13 +08:00 via Android
    很赞同,其他路由都是文件路由的补充,
    搞不懂什么玩意都要路由文件里配置,你能想象一个上千行路由文件,URI 和 controller 完全看不出来,要去搜索,
    结果就是各种重复功能接口
    Varobjs
        22
    Varobjs  
       2020-04-14 09:59:43 +08:00 via Android
    还有个各种框架都跑偏的,就是里面揉了大量设计模式,就为了所谓优雅。个人理解是,设计模式是去揉复杂业务代码的
    tant
        23
    tant  
       2020-04-14 10:07:04 +08:00
    我个人理解的后端框架其实主要分三大部分
    1 、orm:,因为我是从最早那批过来的,已经习惯手写 sql 了,所以这个我觉得可有可无,对于我来说。orm 只能简化数据插入和修改的操作

    2 、路由和模板:这部分还是比较重要 业务逻辑部分都是必须的

    3 、IoC 容器:高级的抽象,这部分 php 应该用不到

    php 其实非常适合中小型项目,没有那么多的抽象和业务逻辑,所以 orm 和 ioc 这部分基本可以不要

    我前几年做过几个 php 项目,就写了个简单的框架,自己用的非常好:
    orm 直接用 pdo 代替,自己在封装一些 helper 函数,这样增删改查就方便了
    路由部分我仿造 java 的注解,用反射获取 php 类的注释自动生成 rewrite 文件,也就相当于是自动路由了
    模板也是直接用的 php 的语法直接 include 就可以了,不需要其他的第三方库
    直接用 autoload 按照规则命名好文件后自动加载不仅自己看着方便,也算半个 ioc 了

    因为用的不多,所以没觉得第三方框架有什么好,对于第三方框架我就觉得 Yaf 挺好的,哈
    ipwx
        24
    ipwx  
       2020-04-14 10:11:44 +08:00
    @king888 @Varobjs 如果所有人都很熟练某个框架,那么大家一起开搞,肯定比大家一起从头开始写,要快得多啊。毕竟有个标准框架在那里,轮子不用造,接口不用约定,奥力给就行了。熟练的框架使用者,一般都比熟练地从头开始写要快得多。不然各个语言就没那么多框架了。

    说白了就是 PHP 开发者熟练使用框架的太少了,所以才感觉小项目开发用框架快不起来。沉浸在舒适区,不愿学习新的生产力,就和 jQuery 一把梭的老人实际上是一致的。当然,近些年前端的复杂性已经使得 jQuery 一把梭的老人越来越少了。至于 PHP,可能要等老一代程序员退出舞台吧?(毕竟 CRUD 有啥难的)
    zjsxwc
        25
    zjsxwc  
       2020-04-14 10:12:53 +08:00
    @Varobjs

    文件路由的好处是直白哪个文件就是哪个路由,
    坏处是可能存在被攻击的漏洞可以任意执行你的每个 php 文件、由于和文件绑定写死了不方便解耦与后续重构与对外对接交流
    tabris17
        26
    tabris17  
       2020-04-14 10:24:57 +08:00
    laravel 的容器不错,但是整个架构谈不上优雅
    JokeEnd
        27
    JokeEnd  
       2020-04-14 10:26:35 +08:00
    传统 php 开发人员跟用框架的开发者差别很大,思维和开发方式也不一样,你说的这些都不是 php 的问题,是开发者本身的问题。
    beyondye
        28
    beyondye  
       2020-04-14 10:27:00 +08:00
    是的太重了,为此我放弃了那些所谓流行的框架,自己写了一个适用自己的 php 框架,https://github.com/beyondye/ENPHP
    svaj
        29
    svaj  
       2020-04-14 10:30:18 +08:00
    thinkphp5 不错,然后基于 thinkphp5 开发的 fastadmin 可以,真正的快捷开发了,建了表 curd 就出来,搜索出来,导出都有,我觉得这个做外包项目挺香的,贼快
    fancy111
        30
    fancy111  
       2020-04-14 10:34:14 +08:00
    前后端每年语言更新不多,花样玩得挺多。
    encro
        31
    encro  
       2020-04-14 10:42:23 +08:00   ❤️ 12
    作为一个从 cake,ci,kahana,zf,yaf,yii1,yii2...一路用过来的人来说,每次接触一个新的流行框架,都学习了一种新的解决问题的办法,每一种框架的流行都是有其道理的,他的道理就是他迎合和解决了那个时段的主要问题。
    至少我用起来,写的代码是越来越安全了,团队效率是越来越高了,而不是越来越低了,代码性能定位越来越容易了,而不是性能问题越来越突出了。

    @dvaknheo

    这东西怎么来的。 一两个特例马上能教人懂,多了没法马上会啊。
    Yii 定位是 advanced 框架,强调是安全、可配置、可扩展、性能可见。不是 ci,cake 等脚手架、helper 类之类的框架。

    View 里不能做任何计算,不能 include 非 View 的代码。
    可以啊,你看的是伪 demo 吧随便找一个,既然是 PHP 文件,不能计算,你是来搞笑的吗? https://github.com/yiisoft/yii-demo/blob/master/views/contact/form.php

    当然可以 include,但是你得搞对路径啊,但是建议采用$this->render 替代。

    Laravel 优雅的带着 PHP 优雅的 Java 化。当初 PHP 上手就干的年代,这是 PHP 的优势。
    上手就干是 4.3 以前的优势,后来的主要优势是社区、开源项目、官方库。


    现在一堆代码,业务相关的没几行,这还是 PHP 么。
    因为已经不需要写这么多业务代码了,你配置好 rule 之后,自动驾驶了,自动驾驶你不应该关心是否有方向盘,而应该是自动驾驶是否可靠。

    ORM 就非用不可么,Data struct 不容易理解么
    有 Yii::$app->db->createCommand 和 Query 任你调用

    有好用的文件路由不用,非得手写路由 (src/Factory/AppRouterFactory.php)
    route 不用任何配置都可以跑的,你用的是官方 demo 么?


    配置文件里一堆 use (config/web.php)
    是的,这次改版最大的变化之一了。
    为了遵守 psr 规范,让各大框架组件能够通用目标,牺牲小我为大我。。牺牲精神值得赞扬,但是我也觉得太多了,其实以前是隐藏的,现在变得开放出来的。也可以理解框架为了变得通用,不得不做各种抽象,比如缓存,日志,数据库为了兼容各种方案,不得采用各种适配器。如果你自己写一个框架,不用兼容那么多场景,那么这块确实是可以简化的(笑)。

    MVC 缺层都是大家的共识了, 业务逻辑层叫 Service 或 Logic 我都无所谓,但直接 Controller 里调用 ORM,以前 10k 行的 Controller 啊。 从 Controller 里把业务逻辑剥离出来,跑命令行测试不好么。
    和 Yii2 无本质区别,加了类型的 PHP 。。。作者 samdark 以前是搞 JAVA 的?或者指使代码写多了,记性不好了,加了类型便于 IDE 方法提示,如果你记性一致很好,那么可以不要这个类型提示,代码一样可以跑的。
    至于你说的 Service 和 Logic 有什么必要吗?参考我上一个回复


    PHP 开发速度很快,运行速度也很快。 没必要为了那些优雅牺牲开发速度,运行速度。
    开发速度,得看工具和生态,Yii 有 gii,有各种数据服务器端,客户端验证,各种第三方库。
    运行速度,性能优化得看性价比、定位速度和解决方案,Yii 等框架提供了 debug,性能问题一目了然。我在一台 4 核 8G 得 CPU 也可以跑一年几亿得交易额,我觉得性能非常好了,如果再发展,我是能花钱可以添加一点机器资源的。Yii 的四层 cache 设计方案,可以让你控制缓存在页面,局部 HTML,数据,请求级别。


    讲真,我动力再足一点,写个同功能的 插进这些框架的 demo 中, 让大家见识一下应该用什么样的手段最符合 PHP 的快速开发模式。
    我倒觉得是时候去框架了,不过我认为值得尝试解决方案是云函数+UI 仓库+项目仓库,看看国内大厂和国外新兴就知道,越来越向 low code 发展了,但是 low code 的基础是大量成熟的解决方案,所以我认为当前符合 PHP 的快速开发模式就是一套成熟的云原生的框架加各种 demo 。其他的话我并不看好。

    @zjsxwc

    symfony 确实是标杆,甚至比以前 zf 做得更好,值得尊敬。目前在 PHP 界都在向 psr 靠拢。

    @HiCode

    1 、PHP 从一开始流行就是因为适合小型项目,开发效率及运行效率都不错;

    同楼上的回复,这是 4.3 以前的优势,后来的主要优势是社区、开源项目、官方库

    2 、PHP 大流行后,部分有追求的程序员希望给 PHP 加一点 B 格,开始用各种模式要求 PHP,让 PHP 往 Java 方向发展。但 PHP 是脚本语言,Java 不是,Java 本身有足够的性能可以支撑起各种设计模式的性能损耗(但还是经常被吐槽太重太慢)——而 PHP 并没有这个性能来支撑。

    PHP 为什么性能不好,知道吗?
    解决性能问题首先要做是定位,通常说 PHP 性能不好的,不能常驻内存导致的吧,至少我还没有发现其他 PHP 性能不好的地方,至少我觉得够用了,举一个其他例子?
    常驻内存可以用 swoole 之类的解决下,当然也没必要仅限于用 PHP 开发。


    3 、各类设计模式在 PHP 项目中的普及,确实提高了效率,增强了一丢丢的团队协作,但开发的复杂性和性能的损耗却让 PHP 失去了他最开始的拥趸。

    PHPer 也可以学习的,而且以前的方式还是可以用啊,为什么大家都愿意用了呢?因为以前的方式已经发展到头了啊,满足需求了啊,新的方式适用新的方向。

    4 、为了追求性能和模式,所谓高手们抛下了 PHP 改用 go 、java 、c#,留下一个所谓“优雅”的 PHP 开发氛围。

    高手们抛弃 PHP 采用 GO,
    不是因为性能和模式。
    而是环境,
    环境变化了,
    恐龙就不能生存了,
    云计算、大数据的环境来了,
    人类为了掌握周边环境降低风险,
    天生就会自动去觉察掌握学习周边环境便于生存,
    go 和 PHP 方向还是不一样的,
    如果你用 go 去开发一个电商网站,
    比如人人商城这类的这时候你会觉得还是 PHP 好,
    如果你去开发一个 FQ 工具或者爬虫或者即时通讯服务端,无疑 GO 跨平台编译,协程让你飞起来。
    如果我们学习后不能思考工具的适用场景,那么就不是真学了,这也是码农和架构师的却别吧,码农拿着锤子都是钉子,架构师所有工具都能恰如其分的使用。
    TangMonk
        32
    TangMonk  
       2020-04-14 10:43:17 +08:00
    吐槽下 symfony 让我学习下
    yc8332
        33
    yc8332  
       2020-04-14 11:27:22 +08:00
    现在 php 都 java 化了。。。真实越来越难搞了。。前端也是啊,越搞越复杂
    dvaknheo
        34
    dvaknheo  
    OP
       2020-04-14 11:33:00 +08:00
    @encro 首先感谢这个回答。
    先从 https://github.com/yiisoft/yii-demo/blob/master/views/contact/form.php 开始
    <?php
    // ...
    echo Alert::widget()
    //..
    ?>
    这地方可以分拆成两个

    alert::Widget() ; 我倾向于从 controller 里直接传入 $html_Alert_widget_sent; 不在这里执行代码。 这块是固定的数据。
    问题不大,只需要在前面加上
    这个 Widget 的东西

    action="<?= $urlGenerator->generate('site/contact') ?>"

    这个问题就大了 $urlGenerator 从哪里冒出来的? 看起来是 url 函数? 为什么不直接写成 url('site/contact') ; 或 _url('site/contact') ;

    XX 从哪里冒出来的?这是看代码最怕的事情之一。

    PHP 有个函数,get_defined_vars(); 再加上 var_dump($this); 基本就能搞定 view 里面的东西了。
    其他 <?= Html::encode($body['subject'] ?? '') ?> 问题不大
    其实最希望的是 View 里 一个命名空间都不用,代码简洁得多。

    ----
    这个严重的

    https://github.com/yiisoft/yii-demo/blob/master/src/Blog/BlogController.php

    ```
    public function index(Request $request, ORMInterface $orm, ArchiveRepository $archiveRepo): Response
    {
    /** @var PostRepository $postRepo */
    $postRepo = $orm->getRepository(Post::class);
    /** @var TagRepository $tagRepo */
    $tagRepo = $orm->getRepository(Tag::class);

    $pageNum = (int)$request->getAttribute('page', 1);

    $dataReader = $postRepo->findAllPreloaded();

    $paginator = (new OffsetPaginator($dataReader))
    ->withPageSize(self::POSTS_PER_PAGE)
    ->withCurrentPage($pageNum);

    $data = [
    'paginator' => $paginator,
    'archive' => $archiveRepo->getFullArchive()->withLimit(self::ARCHIVE_MONTHS_COUNT),
    'tags' => $tagRepo->getTagMentions(self::POPULAR_TAGS_COUNT),
    ];
    return $this->render('index', $data);
    }
    ```
    严重在于 这个 $orm 不知道怎么来的,你知道他是 ORMInterface 接口 . var_dump(get_class($orm)) 知道他是 Cycle\ORM\ORM

    用 debug_print_backtrace(2); 跟踪, 最后得知在 Yiisoft\Injector\Injector 注入进去的。

    OK 前面 Container 部分我肯定没去看文档,直接从代码中学习了。

    现在问题就是,不知道这个 $orm 怎么自己使用, 需要一个 App::getOrm();


    那么,抽出这个有什么意义呢?
    我们要把业务逻辑放在单独地方,用命令行来跑,看结果啊,不然你 10K 行的控制器,后面人改去吧。


    ```
    public function BlogService_GetIndexData(int $pageNum)
    {
    $orm = $this->getOrm();

    $postRepo = $orm->getRepository(Post::class);
    $tagRepo = $orm->getRepository(Tag::class);
    $archiveRepo= $orm->getRepository(Archive::class);

    $data = [
    'paginator' =>$postRepo->getDataForIndex ($pageNum);
    'archive' => $archiveRepo->getDataForIndex(self::ARCHIVE_MONTHS_COUNT),
    'tags' => $tagRepo->getTagMentions(self::POPULAR_TAGS_COUNT),
    ];
    return $data;
    }
    ```
    这样不清晰么。
    --
    希望别超过长度
    jin7
        35
    jin7  
       2020-04-14 11:33:42 +08:00
    直接用 java 就行了
    maddot
        36
    maddot  
       2020-04-14 11:42:48 +08:00 via Android
    小项目感觉还是 Yii1 好用,可惜 xue qiang 好像已经完全不管 Yii 这个项目了
    dvaknheo
        37
    dvaknheo  
    OP
       2020-04-14 12:04:45 +08:00
    @encro
    Yii 定位是 advanced 框架,强调是安全、可配置、可扩展、性能可见。

    安全方面目前没看出来
    配置方面, 框架是否能给默认配置。
    https://github.com/yiisoft/yii-demo/tree/master/config
    一堆配置文件。我的 业务工程,能否不做这些配置也能跑,他们就用默认的配置。

    可扩展性。 哪些扩展不得不在 yii 下使用。

    看到 Injector 用 ReflectionClass,就提一个,为什么非得要反射不可? php 的性能就耗费在这上面。
    我知道 container ,di 的原则是要做到不改动库文件下,实现改动库文件的功能。
    比如 0day 漏洞出现,不强行修改 vendor 目录下的文件 ,直接 在 业务工程 里 添加额外代码迅速临时修复。

    php 的 view 文件,能不计算尽量别计算,这是一条原则。我见过一个 view 模板(非 php 文件)写 sql 计算的烂代码。
    不然还做 V-C 分离干什么。 include, render 算起来是相同说法。


    因为已经不需要写这么多业务代码了,你配置好 rule 之后,自动驾驶了,自动驾驶你不应该关心是否有方向盘,而应该是自动驾驶是否可靠。

    结果就是 Java 那种方法, 结果就跑到研究 rule 上了。 还不如 debug 来的快 . spring struts hibernate 为什么被淘汰了?

    我确实是看的官方代码
    https://github.com/yiisoft/yii-demo/blob/master/src/Factory/AppRouterFactory.php

    没想到路由配置躲在这个地方。

    配置文件里一堆 use (config/web.php)
    是的,这次改版最大的变化之一了。
    重复:有没有默认配置,让我的 业务工程看起来简单。

    至于你说的 Service 和 Logic 有什么必要吗?参考我上一个回复

    Service 层 就是用于命令行运行,直接跑代码看结果的。

    比如模拟某个人操作,没必要用 curl 模拟从他登录开始吧。
    拿到 uid,直接调用 service 业务层就行了。

    开发速度,得看工具和生态
    还有个入门门槛。用丰富的生态和工具,搞死了入门者。

    解决性能问题首先要做是定位,通常说 PHP 性能不好的,不能常驻内存导致的吧,至少我还没有发现其他 PHP 性能不好的地方,至少我觉得够用了,举一个其他例子?

    Laravel 啊,我第一个见到性能出现在代码瓶颈而不是 IO 瓶颈的框架。
    不能常驻内存确实是 PHP 的一个缺点, 在 composer 出现之前。php 引用第三方的代码很少。
    执行完 可数个文件就够了。
    composer 之后,加载就成了个大问题。
    而所有的框架都是一堆文件。
    php7.4 预加载,解决了一部分性能问题。但是并没有完全解决:

    一个请求过来,框架的 hello world 要比纯 php 的 helloworld 跑多出很多 php 代码。
    能减少这些代码量么? 1 性能就是为了使用,我们不优化。2 每次都要对配置里的 path 处理最后一个 / 还不是为了让 sb 使用者不要在 少 / 的时候多出莫名其妙的 bug 检查,类推。

    为了追求性能和模式,所谓 [WEB] 高手们抛下了 PHP 改用 go 、java 、c#,留下一个所谓“优雅”的 PHP 开发氛围。
    james122333
        38
    james122333  
       2020-04-14 12:17:03 +08:00 via Android
    嗯 路由入口就可以做了

    @dvaknheo
    高手有书障啊 读太多反而被迷惑
    dvaknheo
        39
    dvaknheo  
    OP
       2020-04-14 12:18:23 +08:00
    @TangMonk symfony 啊,我印象中就是 laravel 5 的 symfony 组件用的是 symfony 2.3 的, 而 symfony 升级到 3.4 了。万一 symfony 2.3 里有安全漏洞,laravel 5 不就麻烦了。


    symfony 的中文资料太少。

    doctine 和 symfony 的关系 。 在 symfony 网站也没指出来。

    zend framework3 出了个 不同的 html 编码组件,原来 htmlspecailchars 有这么多问题。

    var_dumper 各家都有。

    symfony 作为一个 lib,确实是不错的 lib. 需要轮子的时候,找 symfony,然后找 zend framework3 就是。
    IceBay
        40
    IceBay  
       2020-04-14 12:27:33 +08:00
    @dvaknheo #39

    这台电脑预装的 win7,win7 已经停止更新了,而最新的已经在用 win10 了。

    万一有漏洞怎么办,我还是不用这台电脑了
    james122333
        41
    james122333  
       2020-04-14 12:29:10 +08:00 via Android
    话说个人一直不觉得这是优雅 优雅就要轻
    开坦克觉得是优雅...
    Varobjs
        42
    Varobjs  
       2020-04-14 12:36:46 +08:00 via Android
    是时候推荐你的框架了楼主
    encro
        43
    encro  
       2020-04-14 14:51:47 +08:00   ❤️ 1
    @dvaknheo


    一:



    <?php
    // ...
    echo Alert::widget()
    //..
    ?>

    我个人会选择

    <?=Alert::widget(['class'=>'my-custom'])?>

    更加灵活,而不是从控制器传入,
    框架的核心有一条是逻辑分离,减少大脑负载,
    yii model 负责规则配置、数据操作,
    控制器负责接收请求、组装数据,
    视图负责展示,
    如果采用控制器传入,那么就不是在视图定制了,而是在控制器定制界面,
    如果你连这条不清楚,
    那么你的框架我非常不看好,
    而且会劝别人不要用,
    因为大家会找不到这个界面的代码写在哪里,
    我是不会去维护这样的代码的。


    二:

    action="<?= $urlGenerator->generate('site/contact') ?>"


    Url::to(['site/contract'])方法是可以用的。


    三:

    其实最希望的是 View 里 一个命名空间都不用,代码简洁得多。

    前面有提到视图负责展示逻辑,你记住这句就可以了,只要没有脱离这个本质,再多命名空间,那么代码也是清晰和直白的。

    代码的清晰条理性重要性很重要,你说的 view 一个命名空间不用,Yii 至少有 5 种选择:

    1,将展示逻辑放在控制器;(展示逻辑不分离,不推荐)
    2,隐式引用;(没有代码提示,不好 DEBUG,不直观,不推荐)
    3,模板引擎;(个人认为 php 本身就是最好的模板引擎,不推荐)
    4,采用 ajax ;(这个可以);
    5,调用 rest 接口;(这个也可以)

    你有第六种办法,还是用了其中一种?


    四:

    配置 rule VS 手动 debug

    rule 可以自动生成(gii),改好 rule 就会错误提示一致,不会出 bug,不需要 debug 了,所以这就是自动驾驶,你现在和我说手动挡好?


    五:

    安全

    比如内置了 jwt,rules 验证,cookie 加密,防注入等等,这些基本是目前框架标配吧。
    你感觉不到,因为你看的是普通模板,不是高级模板,普通模板是隐藏了这些的,不表示它不存在,且你没有看官方文档,直接上手一个 demo 了。
    比如需要配置 cookieValidationKey 你知道是做什么用的吗?
    比如为什么配置文件要分为 local 和非 local ?
    environments 里面的 prod 和 dev 又是做什么用的?


    六:

    有没有默认配置,让我的 业务工程看起来简单。


    https://www.yiiframework.com/
    首页 5 个步骤第一个步骤:安装 composer,下载标准模板,运行 yii serve 。
    三行命令项目都跑起来了,进入开发了,你说没有默认配置?



    七:
    比如模拟某个人操作,没必要用 curl 模拟从他登录开始吧。
    拿到 uid,直接调用 service 业务层就行了。

    Model 还可以用,Console 也可以用,其他都可以用,不必重复,
    Yii3 最大的不同和目的就是将 jq,bt 等前端框架从核心中分离出来。
    至于这个 demo 你可以看成秀技术的,Yii 其实一直都是紧跟 PHP 版本的。


    八:

    php7.4 预加载,解决了一部分性能问题。但是并没有完全解决

    还是请举出一个除了不能常驻内存之外的性能问题例子出来,不能说空话啊,写程序的不能空对空,得摆事实。



    九:
    一个请求过来,框架的 hello world 要比纯 php 的 helloworld 跑多出很多 php 代码。

    现实是大家都用框架,WHY ?
    都是大牛们为了优雅好玩的?
    大牛们都傻?
    老板也傻?
    层次不同而已,你看到的是自己写得爽,对其他任来说是团队合作有一套默契的规范,能够高效解决问题。

    十:

    为了追求性能和模式,所谓 [WEB] 高手们抛下了 PHP 改用 go 、java 、c#,留下一个所谓“优雅”的 PHP 开发氛围。

    你还是可以不用框架啊,而且你还是可以自己写一个框架啊,所以有什么好说的。
    环境变了,
    你以为 PHP 还是嵌入 html 中用,
    其实已经经历过我前面提到过的 cake,zend,yii,laravel 多个时代了,
    现在即将进入云原生时代了,
    你期望 PHP 什么都能解决,
    我只期望它做好 Web 即可,
    至少现在开发一个人人商城,微擎这样的软件,我找不到更好的语言,
    至于其他,至少我还会 Python,node,go,还在学习 C++和 C#,哪个适合我就用哪个,有什么好纠结的。



    建议先看完官方手册,以及下载官方推荐的几个开源项目下来用用,然后自己动手写一个商业项目,想想这个框架适合场景,再来评价框架好坏更好。
    当然还需要看下软件工程,软件思想的书籍。
    知道你想骗我,想多从我这里掏点东西,自己快速学走捷径,先满足你吧。
    然后有一天你会明白“欲速则不达”的道理。
    pmispig
        44
    pmispig  
       2020-04-14 15:12:26 +08:00
    php 的框架什么的被 java 带歪了,越来越像 java,没有自己的特色了
    james122333
        45
    james122333  
       2020-04-14 15:15:29 +08:00 via Android
    看来还是我想的够简单 (滑稽
    dvaknheo
        46
    dvaknheo  
    OP
       2020-04-14 18:43:06 +08:00
    @encro
    1.
    widget 的维护还是给程序员。你这种作法也行。
    框架的核心有一条是逻辑分离,减少大脑负载。没错。

    今天我找那个 ORMInfterface $orm 怎么用 App::GetOrm() 的额外方法得到,找了大半天。 自己又 debug 半天,发现全局的 $container 容器是没有的。 虽然全局都在用,但是都传递给构建方法,想自己找都没法搞。 或许是我走歪路了吧。
    我大致知道 得到这个 $container 后, 可以 override 容器里的东西。

    控制器负责接收请求、组装数据, 控制器做外部数据整理和输出,没错。
    控制器基本不负责做业务,业务在 Service 层做。 所以我框架的控制器是不返回任何东西的。
    不希望用户在 Controller 里 dump 一个东西,或者强塞东西塞不了。
    而 yii3 一定要返回 ResponseInterface 这就有一个和 psr 的耦合了。
    而且视图和控制器的方法基本一比一。

    如果采用控制器传入,那么就不是在视图定制了,而是在控制器定制界面,
    那看 demo 的吧

    https://github.com/yiisoft/yii-demo/blob/master/src/Controller.php

    这个 '/layout/main' 怎么解释? ViewContextInterface 又是什么东西?
    为什么 这个基类 Controller 类 要实现 ViewContextInterface ?


    ```
    abstract class Controller implements ViewContextInterface
    {

    public function __construct(

    WebView $view
    ) {
    $this->layout = $aliases->get('@views') . '/layout/main';
    ```
    为什么要 $this->render() ,而不是 View::GetInstance()->render();
    这个基类的还有好多东西不知道怎么冒出来就不要提了。

    ---- 多说一下我 DuckPHP 的作法吧
    https://github.com/dvaknheo/duckphp/blob/master/template/app/Controller/Main.php
    缩减无关代码。
    ```
    <?php declare(strict_types=1);
    namespace MY\Controller;
    use MY\Base\Helper\ControllerHelper as C;
    use MY\Service\TestService;
    class Main // extends BaseController
    {
    public function index()
    {
    $var = C::H(TestService::G()->foo());
    C::Show(get_defined_vars(), 'main');
    }
    }
    ```
    我不知道 yii3 工程的命名空间 App 是否能改,但 DuckPHP 的命名空间是不受限制的。
    多工程拼一起是可以做到的。 甚至你可以把工程变为插件让其他人引用
    DuckPHP 的控制器是没继承任何类的。这就不会让人看到 $this-> 后去看这东西是不是父类里冒出来的。
    而且也告诉你, 你的工程继承可以父类。
    dvaknheo
        47
    dvaknheo  
    OP
       2020-04-14 18:50:25 +08:00
    @encro
    Url::to(['site/contract'])方法是可以用的。 这种方式,应该在 demo 里显示出来。

    前面有提到视图负责展示逻辑,你记住这句就可以了,只要没有脱离这个本质,再多命名空间,那么代码也是清晰和直白的。
    //经常是从输出有问题,才看 View 文件。 我不希望对 HTML 做太大包装,我们要逆向追踪啊。

    在 php 的 view 文件里,这三行能明白 view 文件的运作
    <?php
    var_dump(get_define_vars());
    var_dump($this);
    debug_print_backtrace(2);
    ?>
    第二行, 超大的 View 对象。
    第三行,我居然惊讶的发现 yii3 view 显示的堆栈 和 Controller 的 堆栈根不同。
    dvaknheo
        48
    dvaknheo  
    OP
       2020-04-14 19:01:22 +08:00
    比如内置了 jwt,rules 验证,cookie 加密,防注入等等,这些基本是目前框架标配吧。

    套用 yii 自己说的: [ Be Explicit ]


    https://www.yiiframework.com/
    首页 5 个步骤第一个步骤:安装 composer,下载标准模板,运行 yii serve 。
    三行命令项目都跑起来了,进入开发了,你说没有默认配置?

    然后工程文件里一坨我都不知道有什么用的配置。比如这些:

    https://github.com/yiisoft/yii-demo/blob/master/config/web.php
    ```
    // Router:
    RouteCollectorInterface::class => Group::create(),
    UrlMatcherInterface::class => new AppRouterFactory(),
    UrlGeneratorInterface::class => UrlGenerator::class,

    MiddlewareDispatcher::class => new MiddlewareDispatcherFactory(),
    SessionInterface::class => [
    '__class' => Session::class,
    '__construct()' => [
    $params['session']['options'] ?? [],
    $params['session']['handler'] ?? null,
    ],
    ```
    vendor/yii-web 里有个配置,然后和工程文件里的配置 array_merge 一下不行么?

    DuckPHP 的作法是把能用的默认配置都注释了, 你想要的时候解除注释

    七:

    Model 还可以用,Console 也可以用,其他都可以用,不必重复,

    这个 demo 没体现出这点,就如我说的, 我想看 Blog 页面首页有什么内容,是没有直接的业务接口的。
    我知道还有 api 方式调用但是命令行测试的时候调用一个就行了啊。

    --

    嗯,我有些动力把 DuckPHP 插在 yii3 之前使用,看 DuckPHP 开发相同功能是怎么做的,代码能少多少了。
    encro
        49
    encro  
       2020-04-14 19:38:42 +08:00
    @dvaknheo
    既然你放出了你得框架( https://github.com/dvaknheo/duckphp ),
    那么我就去看一下吧:

    你的 hello world 代码,虽然只有几行,但是存在几个点,我看了之后基本不会用,也会劝别人不要用。

    ```
    <?php
    require_once __DIR__.'/../vendor/autoload.php';

    class Main
    {
    public function index()
    {
    echo "hello world";
    }
    }
    $options=[
    'namespace_controller'=>'\\', // 设置控制器的命名空间为根
    'skip_setting_file'=>true, // 跳过配置文件
    ];
    DuckPHP\DuckPHP::RunQuickly($options);
    ```

    第一:echo "hello world"; 而不是 return "hello world"?直接在控制器里面输出 html 这也是一绝了(绝迹的绝),你想让其他人都学样在控制器 echo html 吗?为什么其他框架都要采用 return 呢?

    第二:namespace_controller 这是什么配置,双斜杆为根,什么奇葩?单独只让自己知道一个标准?我是不看源码心里没底。好的框架不应该直接一看就知道是什么吗?和 yii 的 'controllerNamespace' => 'api\controllers' 比一下,后者我一看就知道是什么意思,我用的着这简写吗,我在给别人还是自己挖坑吗?你真要少代码,因为反正都隐藏了,不如直接不配置,约定俗称。

    第三:skip_setting_file=true 脱裤子放屁?不应该是不写配置就是自动跳过配置吗?


    第四:DuckPHP\DuckPHP::RunQuickly($options)?莫非还有一个 RunSlowly($options)?有什么问题是直接一个 DuckPHP\DuckPHP::Run($options)解决不了的?


    第五:Controller 写在入口文件?这得多 demo 啊?这是 micro/slim/flask 这类函数式框架的写法吧?


    对于你的提到 Yii3 demo 增加了复杂度,我是同样看法的,应该可以更加简单,不妨先看看 yii2 吧,如果 yii3 真就这样,反正不用就是了,现在也在难产中,什么时候出来不知道。
    我 yii 2 目前够用(除了那个和 bootstrap3 绑定外)。

    对于以上评价,可能显得刻薄,请谅解。
    敬佩你写开源框架的精神。

    Yii3 确实被玩坏了,你的判断是对的,我也有这种感觉,团队成员现在动力不大了,因为 PHP 的发展空间就摆在这里,这个轮子不好玩了,意义不大了,我们都要承认。

    PHP 要续命,目前我看只有写出一个好的基于云原生的框架,然后提供这个框架之上的大量现成程序,改下就能用。(类似 thinkphp 的 fastadmin,微擎的应用商店,这些都是中国特色,老外是不屑玩的)。
    jsjscool
        50
    jsjscool  
       2020-04-14 19:39:41 +08:00
    对于开发者来说不实用的问题确实存在,但是放到项目里来说这些"过度设计"是必不可少的。举个简单的例子,你们都要自己设计框架,肯定知道 Active Record 和 Data Mappers 。Data Mappers 很难用,但很多框架直接选择了他。你会选吗?如果多几个人能去思考这个问题,无数勇敢的少年将会创造奇迹。

    程序员都很有个性,同一个人上周写的代码和这周写的差别都非常大。要是项目组超过 2 个人,你会发现编码的自由度越高,项目代码写的就越烂。可参考的规范越少,项目的扩展性就越差。互联网行业不要求每个程序员都能将业务代码封装成独立的 Bundle,但是每个程序员都应该要有"这块功能未来怎样能快速的变成 Bundle"的意识。而这些高级框架帮我们做的就是减少自由度,增加规范,提高内聚,这也是未来的趋势。项目允许有垃圾代码,但是这些垃圾代码影响的范围必须在可控范围内。
    encro
        51
    encro  
       2020-04-14 19:43:07 +08:00
    CoderGeek
        52
    CoderGeek  
       2020-04-14 19:51:26 +08:00
    轻就减少依赖 多框架完全没觉得轻
    自己玩的话怎么舒服怎么来
    hantsy
        53
    hantsy  
       2020-04-14 19:54:36 +08:00
    yii 也是重写了 Prado,好像核心也是有华人。以前那段时间恰好做了 php 项目,用了 CakePHP,Prado 等。Prado 大量的模仿 Apache Tapestry ( Java 框架), 由于性能方面的问题很大,决定重写。

    Yii 第一版本的时候,PHP 5 已经出来一段时间了,但是 YII 开发太保守了,第一版本居然没有 Namespace 支持,还用恶心的前缀命名,我就没跟进关注了。
    encro
        54
    encro  
       2020-04-14 19:57:23 +08:00
    这几个才是正规项目开始的地方。

    yii-base-web,yii-base-api 和 yii-base-cli 这几个参考才是正式开始的地方

    demo 是某些人练手的地方,确实不友好。

    https://github.com/yiisoft/docs 的 Roadmap 还有很多,不知道什么时候呢,我等了 2 年了。
    hantsy
        55
    hantsy  
       2020-04-14 20:03:45 +08:00
    现在自由一点 Micro Framework 也有,Slim,Silex 等。

    Symfony,ZendFramework (现在移动了 Linux 基金会下,https://getlaminas.org/ ,这个名字我都记不住)比较合适开发复杂的程序,特别是 Zend 把 Martin Flower 的企业模式基本都是实现了。Symfony, Doctrine 等完全跟上了 Java 流行框架的步伐。
    weize888
        56
    weize888  
       2020-04-14 20:06:02 +08:00 via Android
    PHP 简单易上手,基本 PHPer 都有写自己的框架。既然大家都来讨论 php 的优雅,我也来献丑一下自己两年前前写的代码。
    https://github.com/weizephp/weizephp
    dvaknheo
        57
    dvaknheo  
    OP
       2020-04-14 20:07:28 +08:00
    @encro
    template 目录还有个完整的例子。 这个例子只是为了演示写在同一个文件。


    一: 也是我困惑的问题,为什么要 Controller 非得要 return 一些东西?初学者最容易搞不懂的就是这个。

    二: 控制器命名空间为 \ 根命名空间。因为常规下是在 ProjectNamespace\Controller 底下的。 这个小例子不需要。 这个例子就是写小型程序用的,这样其他控制器类也直接写。我应该还加上配置扩展选项,使得没服务器配置也能用。追加

    $options['ext']['DuckPhp\\Ext\\RouteHookOneFileMode']=true; //内置扩展类。
    $options[key_for_action']='_r';

    这样可以通过 $_GET['_r'] 来做路由的控制器分发了。 url() 函数的结果 自动切换 a/b 为 _r=a/b,不需要改

    三: 修改默认设置。skip_setting_file=false 目的是为了防止你传代码不传设置文件上去的时候报错。

    四:

    DuckPHP\DuckPHP::RunQuickly($options,$callback) =>
    DuckPHP\DuckPHP::G()->init($options);
    //$callback();
    DuckPHP\DuckPHP::G()->run();

    前者只初始化,后面才开始路由。DuckPHP 不仅仅支持整站配置,还支持非整站的路由设置, 如放到 /something/index.php 里。

    还有 Swoole 兼容的插件, 把初始化部分放在主流程, 运行部分在工作协程。无需改动代码。
    encro
        58
    encro  
       2020-04-14 20:30:50 +08:00
    @dvaknheo
    我知道都能说的通,
    但是一个框架或者一段代码,
    如果不是明摆着的,
    而是需要解释,
    那么就是没人愿意看的愿意用的。


    一: 也是我困惑的问题,为什么要 Controller 非得要 return 一些东西?初学者最容易搞不懂的就是这个。
    所以我们要明白为什么几乎所有流行框架都用 return 呢?其实因为后面方便加 cache 层,加 layout 啊。


    二: 控制器命名空间为 \ 根命名空间。因为常规下是在 ProjectNamespace\Controller 底下的。 这个小例子不需要。 这个例子就是写小型程序用的,这样其他控制器类也直接写。我应该还加上配置扩展选项,使得没服务器配置也能用。追加

    $options=[
    'namespace_controller'=>'\\', // 设置控制器的命名空间为根
    ];

    你改成
    $options=[
    'controller_namespace'=>'Controller ',
    ];
    这样,你的框架又少了一条潜规则(双斜杠),框架不是潜规则越少,越容易学么?


    三: 修改默认设置。skip_setting_file=false 目的是为了防止你传代码不传设置文件上去的时候报错。

    做多了

    $options=[
    'namespace_controller'=>'\\', // 设置控制器的命名空间为根
    'skip_setting_file'=>true, // 跳过配置文件,防止传代码不传设置文件上去的时候报错
    ];

    多别扭,新手关心这个干什么,这个就不是最佳实践



    四:

    DuckPHP\DuckPHP::RunQuickly($options,$callback) =>
    DuckPHP\DuckPHP::G()->init($options);
    //$callback();
    DuckPHP\DuckPHP::G()->run();
    前者只初始化,后面才开始路由。DuckPHP 不仅仅支持整站配置,还支持非整站的路由设置, 如放到 /something/index.php 里。
    还有 Swoole 兼容的插件, 把初始化部分放在主流程, 运行部分在工作协程。无需改动代码。


    试试
    DuckPHP\DuckPHP::run(['mode'=>'swoole'])
    或者
    DuckPHP\DuckPHP::run([],DuckPHP::RUN_MODE_SWOOLE)

    还有这个 DuckPHP\DuckPHP::G()又多了一个方法,写全一点就少了一个隐藏点,仍然是潜规则越少越好,我记不住,大多数人都记不住。大部分时候,显式表达由于隐式表达。

    同事说给我去买个带个午餐上周二你帮我带过的,或者说给我去兰州拉面买个刀削面,当然是后者更不会出错。

    这些基础不搞好,再提性能和架构都是扯。
    JohnH
        59
    JohnH  
       2020-04-14 21:03:58 +08:00
    无意冒犯,看了这么多回复下来,从代码和思想上,楼主所处的阶段应该还是有命名空间以前的时代。

    我想楼主并没有对任何一个框架( Laravel 、Yii2 )进行**长期、深入**的学习使用,否则你的疑惑就不是疑惑了,你自己的轮子也不会是现在的样子(说难听点,可能思维还不到 thinkphp 3.x 时期)。
    dvaknheo
        60
    dvaknheo  
    OP
       2020-04-14 21:04:41 +08:00
    @encro
    一:加 cache 层,加 layout 是在外围的事情,直接 echo 也能加,显式表达 ,性能起见 。Duckphp 没去用中间件,用路由钩子的方式。

    二:这是简单模式,先懂通用模式才回到这种简单模式。 或许我应该加个 $options['mode_simple'] 组合这几个参数。 不是双斜杠啊,转义后是 \ , 根命名空间,

    三:skip_setting_file 因为设置文件是不要存于版本控制里的,所以特意加的限定。而且有提醒看设置文件的作用。 (`mv -T` 不香么)

    四:init() 后的各组件可以用,也是高级用法。 所以为什么给出这个公开方法。初始化之后不一定马上就开始路由了。
    Swoole 支持是通过 DuckPhp\Ext\PluginForSwooleHttpd::class 这个插件开启的。

    G() 这个方法是高级用户用的。 普通用户,只要懂 M,V,C,S, 这四个助手类,还有 DB,Log 对象 够了。

    实现热修复就是靠这个函数。DuckPhp::G()->init() 后,DuckPhp::G() => My\Base\App;
    这个可变单例我在其他地方说过多次了。 替换组件也就是 BaseClass::G(MyClass::G()); 这样后面的 BaseClass::G() => MyClass();

    在开发 DuckPhp 过程中,我经常想的是:不这么做不行么?只有不得已才加上必要的功能。
    dvaknheo
        61
    dvaknheo  
    OP
       2020-04-14 21:08:08 +08:00
    @hantsy slim 只是个路由映射。连 url 函数都没有。写 rest 或许会方便些。
    印象深刻的是 slim 里那个正则。

    同一作者写的 phpparser 不错。
    dvaknheo
        62
    dvaknheo  
    OP
       2020-04-14 21:33:08 +08:00
    @JohnH Laravel 命名空间我也在用。
    laravel 我用过,yii1 有个好产品,一直没看下去。yii2 看了一些没写,然后看看 yii3 所以由此感慨。

    我的疑惑就是从现有产品部署的时候碰到的问题很难追踪然后得来的:有必要搞这么复杂么。
    这么复杂解决了什么问题。 非得要写在框架里么,不做在框架里,作为其他库显式调用,不行吗。

    当初各项目都赶时髦用 Smarty 。我就有这个问题:解决了什么问题? 模板还是要程序员来写。
    HiCode
        63
    HiCode  
       2020-04-14 21:41:33 +08:00
    @JohnH 问题不在于思想属于什么阶段,而在于目前 PHP 是否有必须要以性能为代价去实现这些所谓的优雅?
    hantsy
        64
    hantsy  
       2020-04-14 22:04:24 +08:00
    @dvaknheo 有一个 Routing 和 Middleware 就够, 看起来和 ExpressJS 差不多,其他的 PSR 都标准化,可以选择自己的需要的库用 Composer 安装就完了。
    huijiewei
        65
    huijiewei  
       2020-04-14 22:20:42 +08:00
    yii2 挺好用啊。关键是长期支持呀。。。Laravel 说实话,更新太快,不更吧看着新版本口水,更新吧,好多系统遗留。。。
    whyiyhw
        66
    whyiyhw  
       2020-04-14 22:22:17 +08:00 via Android   ❤️ 1
    框架是为了多人协作的最低规范,PSR 是社区规范。没有这些基本规范,那就更谈不上,composer 标准包。我很难想象这些都没有的 PHP 会在各个类型的 Web 开发中速度特别快,怕不是你要一个人造一个生态? php 一直都像更有效率的地方发展,你说 php 被这些优雅框架玩死了,是真的是没意思。时代变了,你没变(ಡωಡ)
    hantsy
        67
    hantsy  
       2020-04-14 22:27:36 +08:00
    以前玩过 Zend 下 Expressive,现在叫 Mezzio, 刚玩了一下。 @dvaknheo

    现在 PSR 标准化后,太多的选择了,很多组件可以自己选择装配。

    创建项目过程交互式,可以选择一些标准的实现。

    Which container do you want to use for dependency injection?
    [1] Aura.Di
    [2] Pimple
    [3] laminas-servicemanager
    [4] Auryn
    [5] Symfony DI Container
    [6] PHP-DI
    Make your selection or type a composer package name and version (laminas-servicemanager):
    - Adding package laminas/laminas-servicemanager (^3.4)
    - Copying config/container.php

    Which router do you want to use?
    [1] Aura.Router
    [2] FastRoute
    [3] laminas-router
    Make your selection or type a composer package name and version (FastRoute):
    - Adding package mezzio/mezzio-fastroute (^3.0.3)
    - Whitelist package mezzio/mezzio-fastroute
    - Copying config/routes.php

    Which template engine do you want to use?
    [1] Plates
    [2] Twig
    [3] laminas-view installs laminas-servicemanager
    [n] None of the above
    Make your selection or type a composer package name and version (n):

    Which error handler do you want to use during development?
    [1] Whoops
    [n] None of the above
    Make your selection or type a composer package name and version (Whoops):
    hantsy
        68
    hantsy  
       2020-04-14 22:32:11 +08:00
    @dvaknheo 20 年我开始学 PHP 的时候,用 Smarty 我觉得是赶时髦。现在还在用 Smarty,等于回到通讯还是靠送信的方式了。用什么手机,微信,哪有手写的信件优雅。
    hantsy
        69
    hantsy  
       2020-04-14 22:32:32 +08:00
    20 年前。
    james122333
        70
    james122333  
       2020-04-14 23:17:11 +08:00
    @dvaknheo

    是这样没错 一个框架无法解决所有问题 当你要解决的时候 就是架构越来越糟糕的时候
    我知道该怎么形容这种优雅了 是开著坦克车碾压需求带来的快感称为优雅
    HiCode
        71
    HiCode  
       2020-04-14 23:40:33 +08:00
    https://www.techempower.com/benchmarks/#section=data-r18&hw=ph&test=fortune&l=zik073-f

    看数据吧,优雅的代价是什么自己判断,有钱的土豪请忽略。

    我们其实要讨论的不是“要不要跟随时代进步?”,进步是必须的——命名空间也好,psr 也好,我们支持好的技术,遵守好的规范。

    但是进步路上有不同的方向,有不同的诉求,我觉得 PHP 当前的问题是,一味的追求优雅,追求设计模式,过度忽略性能影响——这样的氛围是否应该?是否有利于 PHP 的发展?
    charlie21
        72
    charlie21  
       2020-04-15 00:40:57 +08:00 via iPhone
    少来了,既然是做 PHP 的都知道为了赶工期什么都做得出来
    charlie21
        73
    charlie21  
       2020-04-15 00:43:31 +08:00 via iPhone
    谁管你规范阿,谁管你分层架构阿,若听你们的了 项目做不完了 你能负责吗?你早跑没影了
    tailf
        74
    tailf  
       2020-04-15 01:22:01 +08:00
    @ipwx 有内味了
    jhdxr
        75
    jhdxr  
       2020-04-15 03:13:12 +08:00
    @dvaknheo

    > 严重在于 这个 $orm 不知道怎么来的,你知道他是 ORMInterface 接口
    建议你去了解一下依赖注入这个概念。了解指的是:为什么要这个用(这个概念是怎么产生的)以及这个概念怎么用

    > 也是我困惑的问题,为什么要 Controller 非得要 return 一些东西?初学者最容易搞不懂的就是这个。
    > 一:加 cache 层,加 layout 是在外围的事情,直接 echo 也能加,显式表达 ,性能起见 。Duckphp 没去用中间件,用路由钩子的方式。
    @encro 已经举了例子了,就是为了能够在不去改动 controller 代码的前提下,对响应做一定的处理。此外就是能够控制真正去输出内容的时机(特别是考虑到 header()之类的情况)
    用 echo 的确不是不能做,但用 ob_xxx 系列的方法难道不是性能更糟糕么?


    > 实现热修复就是靠这个函数
    你对热修复怕是有什么误解。热修复是程序在运行过程中去替换部件。对于 PHP 来说,一般直接覆盖文件就完事了。另外你这个函数能做到的,依赖注入也都行。


    > 我的疑惑就是从现有产品部署的时候碰到的问题很难追踪然后得来的
    建议学会使用断点功能。线上环境建议多打日志。

    ---

    最后,现在已经 2020 年了,php 也早就过了可以一个框架单打独斗的年代了。很多吐槽复杂 /没必要那么设计的,你们对于使用别人的轮子这件事情,是不是还停留在坚决抵制,或者复制粘贴的年代?
    jhdxr
        76
    jhdxr  
       2020-04-15 03:23:18 +08:00
    @charlie21 规范、架构之类的很多时候是为了未来考虑的。
    (看到你最近发的那个主题多说一句)将挖坑的经验重复很多年,那你将来挖坑的速度比不上别人,被淘汰是必然的。
    angryfish
        77
    angryfish  
       2020-04-15 08:22:39 +08:00 via iPhone
    看了 php 的那些框架,我何不直接用 Java?
    lp7631010
        78
    lp7631010  
       2020-04-15 08:50:52 +08:00
    @angryfish 你这话就像是“何不食肉”,虽然比喻可能不对,但就是那个感觉
    HiCode
        79
    HiCode  
       2020-04-15 09:25:15 +08:00
    当优雅的框架 laravel,将性能降到原生 PHP 的 4%左右,我就想知道,是不是各位都是土豪(亦或各位的老板都是土豪)?

    我不反对复杂、不反对设计,但我反对过度设计导致的性能低下,请看数据,不是降到 40%,而是降到 4%!!!

    用 @angryfish 的话说:看了 php 的那些框架,我何不直接用 Java?

    PHP 应该学设计模式,应该通过“有限度”的复杂设计来提高开发效率,帮助团队开发,但有必要加一个限制。

    羡慕各位土豪!
    couashi
        80
    couashi  
       2020-04-15 09:28:21 +08:00
    用鸟哥的那一套框架是真简洁
    meshell
        81
    meshell  
       2020-04-15 09:41:06 +08:00
    @ipwx 写业务的那个不是 curd?
    meshell
        82
    meshell  
       2020-04-15 09:47:29 +08:00
    @yc8332 工程化吧。
    meshell
        83
    meshell  
       2020-04-15 09:51:44 +08:00
    @hantsy Silex 还用这个。。早不维护了。。
    encro
        84
    encro  
       2020-04-15 09:56:31 +08:00
    @HiCode

    首先,laravel 将性能降低到原生 4%左右,这个标准是什么,难道我们平时只开发 hello world ? laravel 哪个地方导致性能低了有清楚吗?是不是某个配置,某个插件导致的?不用这个配置或者插件行不行?环境配置是怎样的?有没有开启 opcache 呢,首次运行还是非首次运行?

    如果不清楚这些,你只是人云既云的的程序员,没事瞎起哄。


    其次,laravel 性能很重要吗?我前面提到真实环境一个 4 核 8G 一年也能跑上亿交易额,每天几千单。对我和我的团队来说,用框架我能快速定位性能问题,快速上线,统一标准统一文档代码容易维护能让我节省多少时间,团队少招聘的人,用来给其他程序加工资不更好吗?


    ps:

    我自己实际测试的时候,YII2,5 年前购买的笔记本 4c8g,linux 系统,fpm 配置了 150 最大请求,开启 opcache,代码连接一次 db,纯 PHP 4000rps,框架自带 DB 类不用 ORM 2500rps,用框架 ORM 500rps 。

    实际项目中,我全采用 ORM,平均每秒钟处理 50-200 个请求,nginx 日志显示 fastcgi 响应时间是 5-50ms,我觉得够用了。再不行人员开支上节省的钱,我再加点服务器配置足够了。
    caola
        85
    caola  
       2020-04-15 10:00:09 +08:00
    P++ 已经在路上了……
    HiCode
        86
    HiCode  
       2020-04-15 10:06:38 +08:00
    @encro 标准是什么,我发的那个地址有,这是一个 web 框架性能评测的网站,有详细的测试标准及说明,请自己阅读。

    不仅包含 PHP 的框架,还有其他语言其他框架,我给的链接为了方便大家查看,只筛选了 PHP 框架。

    不是人云亦云,你好好看这个网站的数据,人家已经测试到第 18 期了,先看,看完再评论,不要不看就自嗨。
    HiCode
        87
    HiCode  
       2020-04-15 10:07:45 +08:00
    @encro 你们的项目很牛逼,你们有钱,我前面的回答里面已经说了,土豪请随意。

    你们是土豪,可以忽略无视我的,谢谢!
    jowan
        88
    jowan  
       2020-04-15 10:22:54 +08:00
    @HiCode 你这个榜单 我看了第 18 期 几乎没什么设计模式的 CI 都比 Laravel 排名低
    而且测试的内容就是 hello word 呀 你想表达什么?
    HiCode
        89
    HiCode  
       2020-04-15 10:38:05 +08:00
    @jowan 我可没说 ci 这种“不优雅”性能就好,你看过 ci 的代码就知道它为了方便开发者,各类初始化配置及自动加载会产生不小的性能损耗。

    记住了,优雅,会产生性能损耗,反对过度设计——这是我说的,我认为的,我所表达的。

    但,不优雅也有多种,不优雅也可以绕着远路产生性能损耗——ci 的是这一种。

    你不能把我所强调的“避免过度优雅”等同于 ci,这两者扯不上关系的,请更正这个认识。



    讨论真费力。
    encro
        90
    encro  
       2020-04-15 10:38:45 +08:00
    @HiCode

    才看到你前面发的链接,看了下测试代码和环境,比较公平和准确。
    收回我前面的话,说声抱歉。


    Single query On Cloud

    PHP 15,248
    php-laravel-query-builder 4,867
    yii2 2,545
    laravel 1,087

    Multiple queries On Cloud
    php 1,897
    yii2-raw 1,677
    yii2 919
    php-laravel-query-builder 825
    laravel 430

    这个是非常有意义的:
    随着页面查询增加,性能差别变少。且这都是在框架不开启数据缓存的情况下。
    如果开启缓存,那么就。。。作弊了。。。


    你是希望轻量级框架,这个也已经有很多轮子也多了。如 slim,micro 等,
    但是为什么我们知道的少?
    我认为应为太容易了啊,很容易就自己造一个,所以大家都自己造去了,导致不集中没有流行广的框架。

    ROR,django, yii, laravel, symfony 都是比较重量级的,
    适合团队有前端,后端,API 接口规模的,
    当然熟练了,也可以在小团队适用,比如我现在就是 3 个后端采用 YII2 的,2 年时间大小开发了十来个公司自己用的系统 3 个产品吧,目前在用的还有维护和用的有十个左右。如果不用框架,或者用简单的框架我认为做不到。基本我们是九五六吧。

    yii raw, php-laravel-query-builder, symfony 等等很多框架都提供了针对 api 的简洁版本。

    其实不用 orm 性能就能直接上升一倍以上,但是我还是在我团队让大家优先用 orm,因为维护简单,只有处理个别大量数据导入导出会用到 DB 类和原生 sql.
    jowan
        91
    jowan  
       2020-04-15 10:40:13 +08:00
    @HiCode 请您赐教一下 您现在用的什么?另方便问下您一直在追求高性能,方便了解下你们的业务最大 QPS 大概有多少吗?
    jowan
        92
    jowan  
       2020-04-15 10:48:02 +08:00
    @encro 缓存本身就是一种解决性能的方式,为啥算作弊呢 比 laravel 的 config 和 routes 生产环境开启缓存 0 成本为啥不用呢
    HiCode
        93
    HiCode  
       2020-04-15 10:51:23 +08:00
    @encro 我们目前的问题是,PHP 圈是否存在过度强调“优雅”的氛围?我觉得需要适当的反思这种情况。

    框架是一定要用的,这是生产力工具,以一定的性能损耗换取开发效率提高非常有意义。

    你的技术和经验都是我们其他人所达不到的,有时候更需要你们来考虑 PHP 的发展,来发声让 PHP 能够获得更长久的发展。
    HiCode
        94
    HiCode  
       2020-04-15 10:52:53 +08:00
    @jowan 我只是因为穷才追求高性能,我的业务都是薛定谔的“qps”,爆不爆发看策划看设计,我只负责打造一个“低成本高效率”的系统。
    HiCode
        95
    HiCode  
       2020-04-15 10:55:06 +08:00
    @jowan 我自己抄了一个框架,技术能力太菜,只能到处看别人的代码抄一抄,不开源,因为没时间应对各种小白询问。
    dvaknheo
        96
    dvaknheo  
    OP
       2020-04-15 10:59:08 +08:00
    @jhdxr 恕我浅薄,我真不知道依赖注入,对于动态语言,除了解决 [调用方式不变,实际实现可变] 功能之外还能有什么用。

    各 php 框架内部不用 ob 系列方法实现么?超长字符串拼接效率高还是 ob 函数分段输出效率高?

    我所说的热修复,就是不强行去改第三方库的代码,修复出第三方库出现的功能。

    就是要跟踪到第三方库还没解决问题,这才是折腾。

    第三方 lib 能学用当然用。吐槽的是 framework .
    mitu9527
        97
    mitu9527  
       2020-04-15 11:19:08 +08:00
    以前 PHP 的主要用途就是微型、小型项目,使用面向过程(事物脚本)直接开干当然合适。面对业务逻辑复杂的中型、大型项目,你用面向过程试试,不作死自己就怪了。这几年 PHP 的发展趋势就是面向对象化且提高性能,以支撑中型、大型项目。至于你说的什么 ORM 那也不是 PHP 导致的,想要开发中型、大型的项目,一般都是用分层架构和领域模型,在配合测试和工具链等,才能保证项目成功。直接开干的时代已经过去了,不论哪种语言。至于过度“优雅”这种观点,哪种技术变成主流不都是从“上头”开始的,如果开始都不愠不火,后面谁还搞。
    encro
        98
    encro  
       2020-04-15 11:19:32 +08:00
    @jowan
    性能测试的时候,开启 opcache 是公平的,HiCode 给的连接也是开启了 opcache 的。
    如果开启数据缓存,有的框架没开启,这就不公平了,不好比了,开启后命中率等影响较大。

    而且缓存级别也是有很大差别的,比如 head 直接返回 304 HTTP 304,直接 http 头设置一个超时时间两者区别都很大啊。比如 Yii 的请求,页面,widget 局部,data 级别缓存,每一级性能差别都很大啊。如果我开发一个 blog,为了测试性能好,我直接设置一个一小时过期头,那么其他框架都别比了,原生都别比了。。。所以是作弊。。。规则就是咱还是比谁代码写的好吧。

    但是生产环境,可以根据情况设置缓存。

    框架性能只是架构其中一个考量,大部分公司而言,都放不到第一,人员招聘容易度和开发维护成本重要程度都比它高得多。
    nicoljiang
        99
    nicoljiang  
       2020-04-15 11:33:03 +08:00   ❤️ 1
    PHP 这个语言的定位就是做小工具或者单纯项目的。
    搞出这些框架的人,就是想涨工资,又不愿意学更适合其场景的语言(说是因为喜欢 PHP,但他可能已经忘了当初为何喜欢 PHP,所以就是懒,不想离开 PHP 的舒适圈)
    所以就把这个生态搞得人不人鬼不鬼。
    nicoljiang
        100
    nicoljiang  
       2020-04-15 11:34:35 +08:00
    明明可能有另一条更适合的路可以走(类似 lua 、python 的方向),非要搞得像垂死挣扎一样,死赖在所谓的「企业级复杂业务场景」。
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1025 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 22:20 · PVG 06:20 · LAX 15:20 · JFK 18:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.