DuckPhp 1.2.4 发布,终极架构,文档完善了

2020-05-16 10:14:21 +08:00
 dvaknheo
项目地址: https://github.com/dvaknheo/duckphp
作者 QQ: 85811616
官方 QQ 群: 714610448

phpstan 第 7 级检查通过。php-cs-fixer 代码风格通过。phpunit 全覆盖测试通过。

名称统一成了 DuckPhp,和命名空间一样。

重复一下 DuckPhp 的特性:
+ 可以在不改动库文件下,替换所有实现。
我用 CodeIgniter 的时候,基本上没见到个 CodeIgniter 系统代码是官方原版的。都是各种魔改。
Composer 时代之后,直接改 vendor 的文件确实是不可取的
所以满足在不改动库文件下,替换所有实现这是对现代框架的基本要求。不实现这个目标的框架没存在意义。

+ 可以非固定全站使用的框架。
很多框架都要要求你配置整站才能使用,DuckPhp 很灵活,不需要配置成整站。
甚至启用自带扩展能做到连 Web 服务器都不用配置的单一入口文件模式。
还有一种玩法是 A ,B 两个项目独立开发,然后合在同一个服务器上。
其他框架很麻烦,命名空间都是用 App,路由处理还要折腾很多。
DuckPhp 不同项目不同命名空间,B 项目作为 A 项目的插件使用。

+ DuckPhp 秉着 代码和 DuckPhp 关联越少越好的原则
核心工程师写的非业务核心代码才会和 DuckPhp 耦合。
应用工程师写的业务代码是不和 DuckPhp 耦合的。

+ DuckPhp 是无第三方依赖的单一的 Composer Library
这点很重要么? 很重要。引用的第三方组件出了 Bug 人家升级了怎么办。
Library 则很方便的插入第三方框架里使用。
DuckPhp 工程的初始化就是 复制 template 目录,修改相应模板。
甚至可以直接运行 template 目录。

--

从 CURD 角度的应用工程师角度来看,基本不需要动什么。

使用 DuckPhp 的感觉就是,默认的就已经足够了。

应用工程里那些高级的东西,让核心工程师来做。
而核心工程师呢,如果不满足,那么就调选项。
如果选项还不行,那就入口类里调整。
更高级的是自己做组件和替换默认组件。
对于应用工程师,就看那些 Helper 函数多出来什么就够了。
var_dump(ControllerHelper::GetExtendStaticMethodList());

最高级的玩法是把当前工程 A 作为扩展给 B 工程复用。
也没什么难度,入口类里加额外代码就是。(引入 AppPluginTrait)



1.2.3 版本,我在 yii3 demo 上内嵌了个 DuckPhp 作为实现版本

https://github.com/dvaknheo/yii-demo

在入口 index.php 处拦截如果 DuckPhp 能实现,则用 DuckPhp 的实现版本,否则继续
所有 DuckPhp 版本的实现的文件,都在一个目录下,可以对比一下。
https://github.com/dvaknheo/yii-demo/tree/for_duckphp/app
之前也折腾过 laravel 的 demo, 结果丫自己的 auth demo 我看的都绕半天,何况其他小白。

用 phpunit-codecoverage 看了一下 thinkphp 5.1 hello world 。1052 / 19241 行代码。
也就是不干什么事情都至少有 1000 行代码空跑了。DuckPhp 是 339/5252 行,所以 DuckPhp 是高效的。
当然,这只是对性能的粗略估计。比如 一个 autoloader 的 file_exists 判断性能上就能顶很多行
(尤其是我在 wsl1 环境下 IO 性能惨不忍睹。
至于 Laravel,我有空看一下是不是跑了一万行代码。

DuckPhp 的 swoole 支持是有的,只不过现在不作为重点了,workerman 有空的话我再看看。
DuckPhp 切换成这些模式是无缝的。 只是我不觉得 web 不是 swoole/workerman 该做的主战场。

现在想找个能很好的演示 DuckPhp 的工程来做。演示一下 DuckPhp 的魅力。
6280 次点击
所在节点    PHP
41 条回复
littleylv
2020-05-16 10:25:49 +08:00
其他还没看,你这个名字能改一下吗? Php 看着超级别扭。专有名词不用按照驼峰规范来的,直接 DuckPHP 没问题的,DuckPhp 反而看着别扭
lifeintools
2020-05-16 10:50:50 +08:00
大概看了 一圈 没看懂。。希望介绍能言简意赅一些
lscho
2020-05-16 11:08:57 +08:00
同一楼,太别扭
xnode
2020-05-16 11:12:10 +08:00
可以叫 DoubleDuck 中文 双鸭
jqh
2020-05-16 11:44:37 +08:00
+ DuckPhp 秉着 代码和 DuckPhp 关联越少越好的原则
核心工程师写的非业务核心代码才会和 DuckPhp 耦合。
应用工程师写的业务代码是不和 DuckPhp 耦合的。
------------------------------------------------------------
这样做的意义在哪里?用框架不就是为了不重复造轮子吗?框架提供稳定成熟的基础功能,让工程师专注于业务的开发,你让核心工程师去造这些轮子我敢说大部分质量都是很糟糕的,至少我待过的公司中使用自研框架(无框架)的公司,代码质量都是不怎么样的。毕竟一个成熟的开源框架,每个细节的设计都是经过成千上万个项目检验提炼后的成果,很多公司所谓自研核心组件就是想当然和幼稚无意义的重复实现。

ControllerHelper::GetExtendStaticMethodList()
-------------------------------------------------------------
还自创代码风格??这么多千奇百怪的风格不累吗?自动加载都知道用 composer PSR4 规范了?编码风格也不能统一一下?

至于 Laravel,我有空看一下是不是跑了一万行代码。
--------------------------------------------------------------
现在还有纠结代码行数的,实际上绝大多数用 PHP 的公司都没必要纠结这点代码行数,开发效率和稳定性才是重中之重
littleylv
2020-05-16 11:52:05 +08:00
+ DuckPhp 是无第三方依赖的单一的 Composer Library
这点很重要么? 很重要。引用的第三方组件出了 Bug 人家升级了怎么办。

--------------------------------------------------------------


这点我不敢苟同。现在那么多的优秀组件(特别是 symfony 家的组件),那么多好的轮子,为什么一定要自己造。“引用的第三方组件出了 Bug”? symfony 家社区那么多用户,有 bug 也是很快发现或很快修复。再说了别人有 bug,你自己造的轮子也有可能有 bug 呀
james122333
2020-05-16 12:45:52 +08:00
支持楼主造轮子
可以证明自己不是搬运工
成千上万项目检验只能说给非专业的人听
littleylv
2020-05-16 13:05:28 +08:00
“php-cs-fixer 代码风格通过。”

--------------------------------------------------------------

我不知道楼主用的谁家的代码风格,我稍微看了代码 https://github.com/dvaknheo/duckphp/blob/master/src/Ext/DBManager.php:

-- psr-1 规定 方法名称 必须 符合 camelCase 式的小写开头驼峰命名规范。:
public static function CloseAllDB()
public static function DB_W()
public function _DB($tag = null)
public function _DB_W()
public function _onException()
public function OnException()

-- psr-1 规定 类的属性名 应该 在一定的范围内保持一致:
protected $before_get_db_handler = null;
protected $use_context_db_setting = true;
protected $beforeQueryHandler = null;
dvaknheo
2020-05-16 13:10:55 +08:00
@littleylv 我系统命名空间是用 DuckPhp,所以统一成 DuckPhp 。 要不,还得把命名空间全调整成 DuckPHP ?


@jqh 不是说核心工程师造轮子,是核心工程师调轮子。应用工程师一个 DuckPhp 命名空间的东西也用不到。
DuckPhp 用 phpstan 检查过规范,phpunit 单元覆盖测试 100% 。

ControllerHelper::GetExtendStaticMethodList() => 这里只是个简写, 其实直接在 MyProject\Base\Helper\ControllerHelper 里字节加就行。 这是写插件的时候的额外方法。

是有自动加自的。

现在还有纠结代码行数的 。
////
fpm 模式下,空跑上万行和 和 100 行区别大了。 而且上万行的代码,意味着核心工程师想调整写功能也不好找。


“引用的第三方组件出了 Bug”? symfony 家社区那么多用户,有 bug 也是很快发现或很快修复。

////
有这么一个框架,引用了低版本的 symfony 组件。symfony 后来升级了。

再说了别人有 bug,你自己造的轮子也有可能有 bug 呀
////
所以现代框架就必须要有出 Bug 的时候可以不硬改系统代码,在工程里改正的方法啊。
dvaknheo
2020-05-16 13:21:29 +08:00
@littleylv .php_cs 文件, 就额外几条规则。你这里说的,没用 php-cs-fixer fix 检查出来。

```
<?php
$header = <<<'EOF'
DuckPhp
From this time, you never be alone~
EOF;
$finder = PhpCsFixer\Finder::create()
->files()
->in(__DIR__.'/src')
->name('*.php')
;
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules([
'@PSR2' => true,
'header_comment' => [
'commentType' => 'PHPDoc',
'header' => $header,
'separate' => 'none',
'location' => 'after_declare_strict',
],
'declare_strict_types' => true,
'binary_operator_spaces'=>true,
])
->setFinder($finder)
->setUsingCache(false);
```

public function _DB($tag = null) 这样的方法是对应 public function DB($tag = null) 的。


用于外部回调。 下划线开始的代码,算是一种特殊风格。

public function _onException()
public function OnException() 刚注意到这应该用 _OnException 。 代码多了,有些地方没注意得过来。

欢迎大家到 Github 上提 Issue 或者在 QQ 群里讨论
oops1900
2020-05-16 14:42:30 +08:00
楼主是不是对 Laravel 有什么偏见。。。
dvaknheo
2020-05-16 17:15:00 +08:00
@iidestiny
Laravel 不能节省运行效率和开发效率。 违背了 PHP 简洁之道。

随手举例子

+ blade 模板 违背了 PHP 代码就是视图的原则
+ 滥用 ArrayIterator foreach, 使得没法 dump
+ orm 使得调试更麻烦了
+ 退化到路由表了。有简单的文件路由不用。
+ 中间件使得调用关系复杂化。
HiCode
2020-05-16 17:33:07 +08:00
看着心疼楼主,又不是人民币,没办法得到别人的喜欢的。

我就不爱做这事了……
wowiwj
2020-05-16 17:57:49 +08:00
laravel 不能节省开发效率和运行效率的结论从哪里得出来的?感觉楼主可能对 php 有什么误解,最好拉一些实际例子列举一些自己轮子优势,这样大家好坏看起来更直观一些,也更有说服力
dvaknheo
2020-05-16 18:27:40 +08:00
@wowiwj
laravel 的运行效率,已经有太多例子了。
laravel 的开发效率:不要指望一个智力水平只有高中的 php 新手去使用并了解其中原理。

最好拉一些实际例子列举一些自己轮子优势。
////
我 fork 了一个 yii3 demo 的分支,用 DuckPhp 1.2.3 实现的。输出和 yii3 的一模一样。

除了入口文件,其他工程文件都在同一个目录下

https://github.com/dvaknheo/yii-demo/tree/for_duckphp/app

可以看 yii3 还是 DuckPhp 更容易明白。DuckPhp 更加朴实无华,不用那么花哨就解决问题。

之前在我本机弄了 laravel 自带的 auth 的版本,发现 laravel auth 连我都没能弄清楚,怎么可能会有国内项目用他那套做验证,都是自己从头起一套更容易。 后面是卡在验证器部分了。 要在不用 laravel 框架的情况下实现和 laravel 做表现一致的验证。后面回头做 DuckPhp 的代码了就没管这个。

@HiCode 谢谢。我希望能有一小撮人搞起。在写文档的时候,总没有底气不知道别人能否看明白。DuckPhp 的精妙之处,在使用之后会明白的。但是我做得出来,说出来就一塌糊涂。DuckPhp 也有些地方,总感觉可以做得更好,但是总是缺一个人提醒一下。
rootx
2020-05-16 18:30:30 +08:00
支持楼主!
DavidNineRoc
2020-05-16 18:49:34 +08:00
随便点开了一个文件,看到了 Core_App
所以楼主是用 sanke 还是 camel 呢。

对于楼主说的话,我就随便反驳几个。
1. Laravel 不能节省开发效率,这句话你是框架第一人。你写个队列任务,写个数据库操作
2. 简单的文件路由,你都知道简单了,为什么还要纠结这个问题呢,文件路由怎么实现 path parameter 呢。
3. 如果一个项目没有中间件,我大概就知道这个项目怎么做登录验证的那种模块了,估计就是每个文件 include auth.php
4. 前面的人也说了,你居然相信你会超过 symfony 家,别人一个人我就不说了,一个社区你想怎么比

从 CURD 角度的应用工程师角度来看,你都觉得框架不好了,我觉得不用原生 PHP 的都是在放屁 |(-_-)|
explore365
2020-05-16 20:08:48 +08:00
支持楼主
dvaknheo
2020-05-16 21:06:51 +08:00
@DavidNineRoc

1 队列任务不是 Web 框架必备的部分,队列或者应该是单独的一个库。数据库也不是。但是作为常用组件,DuckPhp 通过默认扩展的方式提供主从数据库的支持。另一个默认扩展,就是分页了。 分页在各应用里绝对都是很折腾的方式,所以 DuckPhp 也带了基础的分页,并很容易改写。

2 文件路由,namespace 分割,如果有更特殊需求,加路由钩子。

3 路由前后钩子。中间件搞得堆栈混乱一堆。中间件还存在为调用顺序折腾的事。 如果路由钩子多起来,那么我会提供调用方式调整的方法,但是希望是手动。

4 一个社区也是由一小撮人慢慢发展起来的。并不是说 symfony 不好。为什么能推广开的是 laravel 而不是 symfony 我很奇怪。 比如 html 编码。 我提供了一个默认方式,zend framework 有更好的方式,你可以很容易的去替换成 zend framework 。symfony 的例子意思是可靠性最好不要建立在 第三方基础上,而是自己有实现,也可替换成第三方实现。

因为我闭门造车,很多小的细节不可避免的有问题,目前就是希望能有一小撮人一起来讨论,做好。
dvaknheo
2020-05-16 21:22:36 +08:00
@DavidNineRoc
3. 如果一个项目没有中间件,我大概就知道这个项目怎么做登录验证的那种模块了,估计就是每个文件 include auth.php

这个问题我再说明一下,我刚才答错了。
DuckPhp 项目,推荐的是用 PHPer 最习惯的方式,在控制器基类构造函数里做权限判断。好处是你从代码看起的时候不会发懵:为什么这里会有个验证? 这也就是 DuckPhp 尽量避免的,这玩意从哪里来。

我答成了使用第三方类 auth 类做验证了。
如 template 目录下的例子。

http://duckphp.demo.dev/full/public/u/index.php/login

对应的文件应该是 template/full/public/u/app/Controller/Main.php (暂时别吐槽为什么文件这么长了。
但是没看到 login 方法。
因为在
template/full/public/u/app/Base/App.php 的 oninit 里有这么几句。
$this->options['ext']['UserSystemDemo\Base\App'] = true;
$path = realpath($this->options['path'].'../../auth/');
$this->assignPathNamespace($path, 'UserSystemDemo');
后两句是 autoload 添加 'UserSystemDemo' 命名空间。
重点是第一句
把 template/full/public/auth 这个项目作为扩展来用于 auth.
template/full/public/auth/Base/App.php 只需要一句,就把这个独立工程可插件化了。
use AppPluginTrait;

独立运行 auth 项目的入口是
http://duckphp.demo.dev/full/public/auth.php

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/672263

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX