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

对主流框架不感冒,想开发属于自己的框架,寻求不同见解或同好朋友

  •  
  •   gavinczhang · 2017-07-17 00:13:36 +08:00 · 6506 次点击
    这是一个创建于 2715 天前的主题,其中的信息可能已经有所发展或是发生改变。

    simple 框架

    simple 框架(github)是一款简单、高效、易用的 PHP 开发框架。

    为什么要有 simple 框架

    • 学习 /锻炼 /积累 /实践 /进步
    • 现有的框架太臃肿,部分包含了大量的 jQuery 等前端代码,而日常的后端开发工作中并用不到此类的依赖。
    • 无存在意义的模板引擎。
    • DI、IoC 等设计思路下设计出的框架,学习成本较高。
    • 做过相关压测,主流框架大部分性能较差。压测数据

    从 0 到 1

    基于上述逻辑,整理下一个框架所需要实现的功能,及所有功能所需要的积累。

    设计思路

    我认为作为一个后端底层框架,只需要为开发者提供最核心最常用的功能即可,其中包括:

    • composer 支持 /目录结构符合 PSR-4 规范
    • 错误机制
    • config
    • route/mvc
    • request/response
    • DB/ORM
    • CLI
    • cookie/session
    • Log/curl/iptable/redis 等锦上添花的类库

    框架架构图

    架构图

    涉及技术

    composer

    composer 是 PHP 用来管理依赖( dependency )关系的工具。可以在自己的项目中声明所依赖的外部工具库( libraries ),Composer 会安装这些依赖的库文件。

    基于 composer 开发的代码,可以让使用房快速加入自己的项目中,且可以很好的管理需要使用的版本。另外框架约定好按 PSR-4 规范后开始开发,可以省去了 autoload 的工作量(当然是有代价的,曽压测过使用 composer 的 autoload 和自己实现 autoload 的性能大概相差 15%,但是当项目足够大,需要依赖的外部资源足够多时,这个差距会逐渐的缩小)。

    错误机制

    保证框架运行过程中的健壮性,当框架捕获到相关异常,允许用户自定义异常处理方法,可以快速开发出满足自己业务逻辑的功能模块(例如快速实现 404/500/异常上报等功能),以及调试模式下快速定位问题。

    config

    用于快速读取配置文件,通过定义的预定义常量自动读取对应环境的配置。

    route/mvc

    route 即路由机制,通过 url 匹配一段规则后,找到对应处理的类和函数。 MVC 为模型-视图-控制器模式,用一种业务逻辑、数据、界面显示分离的方法组织代码,已经成为 web 开发的必会标准模式。

    request/response

    深入了解 HTTP 协议的 request 和response

    DB/ORM

    选用 mysqli 或 pdo 实现 DB 的基本 query/fetch/insert_id 等操作。 在此基础上,实现 SQL 语句的快捷构造封装 SQL builder (将数组生成对应 SQL 语句)。 在此基础上,实现 ORM (对象-关系映射)的基本封装

    CLI

    在日常的开发工作中,定时脚本任务的开发必不可少,因为便捷的开发基于 CLI 模式运行的脚本也是必须要满足的条件。

    cookie/session

    Log/curl/Iptable/redis 等锦上添花的类库

    Log 用于调试开发等方便打印日志输出。 日常工作中经常需要发送一些 http 请求到特定服务器,或从某服务器拉取相关数据,curl 使用率非常频繁。 在提供纯接口 server 时,对 ip 段限制的需求会经常遇到。 redis 发展到今天,无论是做缓存,还是作为稳定可靠的 DB 提供服务都毫无问题。

    写在最后

    目前 simple 框架不断优化、调整,已经迭代至 4.0 版本,有了近两年时间的思考和积累,某些代码的实现确实需要改进,因此有了 5.0 版本的规划和思考。准备将 5.0 版本开发过程中的一系列问题一一记录在案,并对 route、DB build、curl 等一些类库的封装思路进行详细的说明。

    我也希望能有认同我观点的朋友参与进来一同思考、讨论、开发,也希望有不同观点的朋友能提出各种批评或者建议,让我们共同探讨技术,一同进步。

    欢迎各种吐槽。 原文地址

    44 条回复    2017-08-22 14:37:20 +08:00
    voocel
        1
    voocel  
       2017-07-17 01:38:06 +08:00
    deepkolos
        2
    deepkolos  
       2017-07-17 01:58:49 +08:00
    自己造过一个小小框架 , 不过各各部件的抽象成都不高, 属于过程的复用级别 , 大量使用魔术方法 get set 并借此实现了一个函数级别的 Hook 机制, 然而并无卵用属于过度设计... 感觉框架的意义在于把一些任务变成写配置文件

    还有前后端的分离 , 后端 view 层感觉变成了前端的 model 层了, 还有后端的 Route 也不是对应页面了

    这是我的小小框架的造出来的东东~玩具级的~ http://weibao.deepkolos.cn
    shiji
        3
    shiji  
       2017-07-17 02:15:07 +08:00   ❤️ 1
    造轮子喜闻乐见。 以后能不能流行不重要,这一路估计能积累不少经验
    sagaxu
        4
    sagaxu  
       2017-07-17 06:12:22 +08:00 via Android
    你这性能测试结果诡异,我测过 laravel 跑 helloworld 都能 2000rps 了,yaf 才 1000 多?
    acthtml
        5
    acthtml  
       2017-07-17 07:14:41 +08:00   ❤️ 1
    php 框架我只服 drupal
    mytsing520
        6
    mytsing520  
       2017-07-17 07:59:51 +08:00
    适合自己的,才是最好的
    askfilm
        7
    askfilm  
       2017-07-17 08:47:44 +08:00
    干嘛要费这个事造轮子, 有这功夫,symofny 早学会了,现在早就弱化框架这种东西了 , 组件构造一切
    littleylv
        8
    littleylv  
       2017-07-17 09:19:11 +08:00
    造轮子这事,如果是兴趣爱好使然,或者是为了学习、提高自己等出发,非常不错,值得肯定。
    否则,有轮子为啥不用?
    hzw94
        9
    hzw94  
       2017-07-17 09:25:22 +08:00
    厉害厉害
    zhongkouwei
        10
    zhongkouwei  
       2017-07-17 09:32:34 +08:00
    @askfilm 造轮子这个过程很重要吧,可以学到很多东西
    zhengwenk
        11
    zhengwenk  
       2017-07-17 09:36:47 +08:00
    一般想造轮子只有 2 种情况。1、见识不够,觉得自己是天才。2、真的是天才。我觉得楼主属于后者。
    loadinger
        12
    loadinger  
       2017-07-17 09:37:35 +08:00
    感觉 DI、IoC 还是有点意义的.但是这都搞了,为什么不用 laravel....就当学习吧.支持楼主 .
    gavinczhang
        13
    gavinczhang  
    OP
       2017-07-17 09:52:15 +08:00
    @sagaxu 跟机器配置的 fpm 运行数等有关,不过在同样配置环境下看两者差距即可。另外当时压测时没有开启 opcache
    codermagefox
        14
    codermagefox  
       2017-07-17 09:54:05 +08:00
    @zhengwenk 为了学习造轮子的看了看不敢说话
    Immortal
        15
    Immortal  
       2017-07-17 09:55:50 +08:00
    收藏下 准备有空看下楼主代码学习
    dinghua
        16
    dinghua  
       2017-07-17 10:12:59 +08:00
    不敢说话
    juneszh
        17
    juneszh  
       2017-07-17 10:18:02 +08:00
    flight+composer 做 RESTful 杠杠的
    sagaxu
        18
    sagaxu  
       2017-07-17 10:23:47 +08:00
    @gavinczhang 不开 opcache 的压测毫无意义,理由如下

    1. 编译代码的开销不小,且生产环境都没有这个开销
    2. 100000 行代码的框架和 1000 行代码的框架,即便执行了相同的 100 行,编译开销却差百倍
    gavinczhang
        19
    gavinczhang  
    OP
       2017-07-17 10:35:27 +08:00
    @sagaxu 是的,近期我重跑一次
    slion
        20
    slion  
       2017-07-17 11:05:39 +08:00
    收藏,下载来学习下
    akrf
        21
    akrf  
       2017-07-17 11:07:29 +08:00 via Android
    楼主代码写的不错,赞一个
    deepkolos
        22
    deepkolos  
       2017-07-17 11:49:50 +08:00
    [数组操作]
    use \Simple\Arr;
    //$row = isset($array['test']) ? $array['test'] : false;
    $row = Arr::get($array, 'test', false);

    PHP 支持??运算符了 $row = $array['test'] ?? false;
    kancloud
        23
    kancloud  
       2017-07-17 11:50:02 +08:00
    文中提到的评测数据毫无意义 在你不了解每个框架的内部机制的情况下 数据差异是很正常的,而且还涉及到优化的层面,作为一个部署项目,不优化就上线的情况较为少见;
    其次,所有的性能问题随着你的自定义框架的功能完善以及业务场景需求都会不可避免的下降,框架如果仅仅是为了解决部分需求 那根本不需要框架,当你的框架慢慢完善成为主流框架的时候再来做一次数据比较就非常明显了;
    DI 或者 IoC 等设计带来的开发优势 相对于学习成本和性能损耗 是值得的;
    说模板引擎毫无意义的 主要是不想重复造轮子,如果你的应用还是传统的 MVC 模式 模板引擎仍然有意义 ;
    总而言之,性能不是重复造轮子的理由,学习和提升才是重点,但一个框架的实用是否有太多的细节和体验;
    deepkolos
        24
    deepkolos  
       2017-07-17 12:20:00 +08:00
    还有 Curl.php , 可以添加一些常用的小功能方便来使用 : 比如 auto_convert , auto_referer , 还有常用的类型转换 to_json , 我的 Curl 是这样来的使用方式

    $this->Curl->get()
    ->url( URL , array(URL_PARAMS) )
    ->referer( URL )
    ->data() //post 的时候用的
    ->autoConvertTo( toEncode ) //从页面的常用位置提取 fromEncode
    ->convert( fromEncode , toEncode ) //手动指明 fromEncode
    ->headers() //设置 content-type 为非 text , 禁止自动转码, convert 依然生效
    ->getResponse()
    ->json() // 转换为 json
    ->base64() // 转换为 base64

    Curl 的使用方式就是那么方便 , 模仿类的 AutoLoad , 对象的 AutoLoad , 因为滥用魔术方法 , 在 module/component 里面直接调用 $this->Curl 就会得到一个新的实例并挂载到当前对象的$this 下面~然后使用工具函数来配置 , 然后写一个简单的整合 get , parse , store 这个 workflow 的类 , 可以形成一个简单的爬虫框架了~
    jhdxr
        25
    jhdxr  
       2017-07-17 12:24:00 +08:00
    @gavinczhang #19 除开 opcache 的问题,你 laravel 的压测数据也偏低了,我猜你没有关闭 laravel 默认开启的 session ?

    另外关于你博客中的脚手架部分的回答。我个人的回答是,在新项目启动的时候肯定用的到的(或者你会从以往的项目中复制一些需要的东西过来),而到后来不合适的部分会被慢慢重构掉。
    gavinczhang
        26
    gavinczhang  
    OP
       2017-07-17 12:57:18 +08:00
    @jhdxr 确实没有,laravel 还有哪些可以关闭的,我关一下再看看?因为对 laravel 不熟,只是看文档写了 hello world,没有仔细找相关调优的文档。非常感谢
    HYSS
        27
    HYSS  
       2017-07-17 13:10:44 +08:00
    @zhengwenk 造轮子居然还被嘲讽了?
    gavinczhang
        28
    gavinczhang  
    OP
       2017-07-17 13:11:51 +08:00
    @kancloud 第一点表示认同,但是我认为框架应该把调优的设置尽可能简洁,比如一个 debug 开关?毕竟不是所有人都能立刻找到所有框架的细节差异,再去针对性调优的,都需要不断学习了解。
    第二点和第四点表示不认同,在绝大多数开发场景下,大部分框架提供的很多工具其实根本用不到,没必要为了在某些情况下可能用到的东西而提前做大的集成,这些完全可以在实际项目开发过程中通过 composer 找一些相关成熟的组件来解决。比如 YII 集成的 jQuery,比如 laravel 集成的和模板关联的表单验证。相信大部分的工作项目中,前后端足够分离的情况下,并用不到这些功能。至于模板引擎,并不能带来多少性能的提升,相反还需要前后端开发同学去学习一门只有此框架才用得到的新语法,得不偿失,php 语法本身就可以做到这些功能。
    第三点,如果我没有理解错的话,提前定义好 interface,通过配置或变量的不同,创建不同的对象并注入 IoC 中,上层使用仅需要使用 IoC 中的对象即可。但是日常开发中偶尔能遇到适合这种场景的业务开发,但是框架层面,请恕我愚钝,暂时没有体会到 DI 和 IoC 为框架带来的优势,比如如果需要从 mysql 换到 oracle 或者 mysqli 换到 PDO ?但是我认真的思考过,这类庞大、重要到需要一整个团队去支撑的事情,又有多少人真的用到过?当然也可能是我的理解错了,对 DI 和 IoC 的使用场景搞错了。烦请指点,多谢。
    gavinczhang
        29
    gavinczhang  
    OP
       2017-07-17 13:13:38 +08:00
    @deepkolos 谢谢交流
    我的思路是把 curl 分成三部分
    option、request 和 response
    option 用来快速构造 curl_option 数组
    request 可以支持并发 /单独调用 curl
    response 去做结果
    近期会重构这部分代码
    wellsc
        30
    wellsc  
       2017-07-17 13:22:25 +08:00 via Android
    @zhengwenk 为了练手想造轮子的默默不说话
    deepkolos
        31
    deepkolos  
       2017-07-17 13:23:59 +08:00
    @gavinczhang 看到了 , 原来这样来放的~~
    gavinczhang
        32
    gavinczhang  
    OP
       2017-07-17 13:25:06 +08:00
    @deepkolos 最初是一个 curl.php ,后来想了想把他拆分了,但是这个还没删。。
    cowpea
        33
    cowpea  
       2017-07-17 13:28:15 +08:00
    支持~
    0x8C
        34
    0x8C  
       2017-07-17 14:02:46 +08:00
    鸟哥在 php 大会上批全栈,现在的年轻人都追求全栈,然后怎样呢?自己写了个博客,前端后台全包圆,但写的漏洞百出,我说你要做博客为啥不用 wordpress 呢,用剩下的时间研究一下目前空白的领域,有点追求好不好
    bellchu
        35
    bellchu  
       2017-07-17 14:13:12 +08:00
    只要能造出更好的轮子,都是对业界的贡献~~~
    ywisax
        36
    ywisax  
       2017-07-17 15:42:18 +08:00
    截图中,swoole 的数据明显不科学。
    我看了下 Simple 的源码,依然是基于 php-fpm 的,如果都是 hello world 绝对没理由跑得过 swoole,我认为“自定义”那里的数据是有问题的。
    另外就个人使用经验来看,Yii2/Laravel/Kohana 在跑 hello world 应该是相同水平,没加上业务基本难分优劣,你的数据差异太大了。
    gavinczhang
        37
    gavinczhang  
    OP
       2017-07-17 16:12:39 +08:00
    @ywisax 你没仔细看。。。是 swoole framework 不是 swoole 扩展
    chenyu0532
        38
    chenyu0532  
       2017-07-17 16:30:49 +08:00
    支持楼主的造轮子精神,我等只能用轮子了。。
    kancloud
        39
    kancloud  
       2017-07-17 16:47:46 +08:00
    @gavinczhang 你可能没明白我的意思,不同的框架默认加载或者启动的类以及请求生命周期各有不同 例如 CI 我记得是默认不开启 Session 的 而其它框架默认会启动,这个对于你这种 helloworld 测试来说的话 数据差异是非常大的。我的建议你的压力测试最好是使用数据库操作,这是最起码的使用场景,谁用框架来写 helloworld ?而且框架不太可能存在一键开启全部优化的情况,你觉得 apache mysql 有开启一键优化的配置么? 框架的使用场景和环境太复杂了,调试模式的关闭不代表你的框架就已经进行调优了;
    框架的重点不是类库,类库的问题无论目前的 Composer 还是以前的类库包都能解决,框架的处理机制和请求生命周期可以做什么以及怎么做,决定了你的功能是否强大,是否方便扩展。数据验证就算是前后端分离,后端依然要验证;
    模板引擎的存在并不一定是为了给开发人员写的,否则 MVC 还有啥意义;
    DI 和 IoC 的优势,如果你了解 Laravel 就明白了;
    那些自诩性能很高的框架我见过很多,代价就是缺少功能以及不够完善(一旦你的用户群越来越大,你会不断增加功能满足这些需求,然后。。。),主流框架在完成相同的功能和机制的情况下,其实性能已经优化的不错了,无论 thinkphp/yii/laravel,所以应该去说你的框架如何好用,而不要用不负责任的测试数据去误导用户(讲真,现在主流框架都不在乎运行性能)
    binjoo
        40
    binjoo  
       2017-07-17 16:53:42 +08:00
    自己造轮子没毛病,不管好不好,至少你会造轮子,你造过轮子。
    zhengwenk
        41
    zhengwenk  
       2017-07-17 17:07:23 +08:00
    @wellsc 嗯 我也觉得练手的话就默默的
    breeswish
        42
    breeswish  
       2017-07-17 18:39:08 +08:00
    楼主嫌一个大框架组件多有些要替换的话可以用 Symfony 自己组合呀

    config -> symfony config
    route -> symfony routing / fastroute
    request/response -> symfony http foundation
    db/orm -> symfony database (doctrine)
    cli -> symfony console
    cookie/session -> symfony http foundation
    Log -> monolog
    curl -> requests
    template -> twig
    jarlyyn
        43
    jarlyyn  
       2017-07-17 18:48:32 +08:00
    做框架很正常啊,一般用着用着就有需求做框架了。

    但自己写框架不是应该是流行框架有和自己的业务流程不符的地方,或者不想被流行框架的版本升级绑架么……

    也就是不是流行有缺点。

    而是自己做框架能解决痛点……
    fantiq
        44
    fantiq  
       2017-08-22 14:37:20 +08:00
    开发一个再也没争议的框架,工具齐全,可以吃几年的那种。
    不过要把 php java go nodejs 这些语言的框架研究一遍,总结出一个更好的~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2847 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 12:19 · PVG 20:19 · LAX 04:19 · JFK 07:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.