1
littleylv 2020-05-16 10:25:49 +08:00 6
其他还没看,你这个名字能改一下吗? Php 看着超级别扭。专有名词不用按照驼峰规范来的,直接 DuckPHP 没问题的,DuckPhp 反而看着别扭
|
2
lifeintools 2020-05-16 10:50:50 +08:00
大概看了 一圈 没看懂。。希望介绍能言简意赅一些
|
3
lscho 2020-05-16 11:08:57 +08:00 via iPhone
同一楼,太别扭
|
4
xnode 2020-05-16 11:12:10 +08:00
可以叫 DoubleDuck 中文 双鸭
|
5
jqh 2020-05-16 11:44:37 +08:00
+ DuckPhp 秉着 代码和 DuckPhp 关联越少越好的原则
核心工程师写的非业务核心代码才会和 DuckPhp 耦合。 应用工程师写的业务代码是不和 DuckPhp 耦合的。 ------------------------------------------------------------ 这样做的意义在哪里?用框架不就是为了不重复造轮子吗?框架提供稳定成熟的基础功能,让工程师专注于业务的开发,你让核心工程师去造这些轮子我敢说大部分质量都是很糟糕的,至少我待过的公司中使用自研框架(无框架)的公司,代码质量都是不怎么样的。毕竟一个成熟的开源框架,每个细节的设计都是经过成千上万个项目检验提炼后的成果,很多公司所谓自研核心组件就是想当然和幼稚无意义的重复实现。 ControllerHelper::GetExtendStaticMethodList() ------------------------------------------------------------- 还自创代码风格??这么多千奇百怪的风格不累吗?自动加载都知道用 composer PSR4 规范了?编码风格也不能统一一下? 至于 Laravel,我有空看一下是不是跑了一万行代码。 -------------------------------------------------------------- 现在还有纠结代码行数的,实际上绝大多数用 PHP 的公司都没必要纠结这点代码行数,开发效率和稳定性才是重中之重 |
6
littleylv 2020-05-16 11:52:05 +08:00
+ DuckPhp 是无第三方依赖的单一的 Composer Library
这点很重要么? 很重要。引用的第三方组件出了 Bug 人家升级了怎么办。 -------------------------------------------------------------- 这点我不敢苟同。现在那么多的优秀组件(特别是 symfony 家的组件),那么多好的轮子,为什么一定要自己造。“引用的第三方组件出了 Bug”? symfony 家社区那么多用户,有 bug 也是很快发现或很快修复。再说了别人有 bug,你自己造的轮子也有可能有 bug 呀 |
7
james122333 2020-05-16 12:45:52 +08:00
支持楼主造轮子
可以证明自己不是搬运工 成千上万项目检验只能说给非专业的人听 |
8
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; |
9
dvaknheo OP @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 的时候可以不硬改系统代码,在工程里改正的方法啊。 |
10
dvaknheo OP @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 群里讨论 |
11
iidestiny 2020-05-16 14:42:30 +08:00
楼主是不是对 Laravel 有什么偏见。。。
|
12
dvaknheo OP @iidestiny
Laravel 不能节省运行效率和开发效率。 违背了 PHP 简洁之道。 随手举例子 + blade 模板 违背了 PHP 代码就是视图的原则 + 滥用 ArrayIterator foreach, 使得没法 dump + orm 使得调试更麻烦了 + 退化到路由表了。有简单的文件路由不用。 + 中间件使得调用关系复杂化。 |
13
HiCode 2020-05-16 17:33:07 +08:00
看着心疼楼主,又不是人民币,没办法得到别人的喜欢的。
我就不爱做这事了…… |
14
wowiwj 2020-05-16 17:57:49 +08:00 via iPhone
laravel 不能节省开发效率和运行效率的结论从哪里得出来的?感觉楼主可能对 php 有什么误解,最好拉一些实际例子列举一些自己轮子优势,这样大家好坏看起来更直观一些,也更有说服力
|
15
dvaknheo OP @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 也有些地方,总感觉可以做得更好,但是总是缺一个人提醒一下。 |
16
rootx 2020-05-16 18:30:30 +08:00
支持楼主!
|
17
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 的都是在放屁 |(-_-)| |
18
explore365 2020-05-16 20:08:48 +08:00
支持楼主
|
19
dvaknheo OP @DavidNineRoc
1 队列任务不是 Web 框架必备的部分,队列或者应该是单独的一个库。数据库也不是。但是作为常用组件,DuckPhp 通过默认扩展的方式提供主从数据库的支持。另一个默认扩展,就是分页了。 分页在各应用里绝对都是很折腾的方式,所以 DuckPhp 也带了基础的分页,并很容易改写。 2 文件路由,namespace 分割,如果有更特殊需求,加路由钩子。 3 路由前后钩子。中间件搞得堆栈混乱一堆。中间件还存在为调用顺序折腾的事。 如果路由钩子多起来,那么我会提供调用方式调整的方法,但是希望是手动。 4 一个社区也是由一小撮人慢慢发展起来的。并不是说 symfony 不好。为什么能推广开的是 laravel 而不是 symfony 我很奇怪。 比如 html 编码。 我提供了一个默认方式,zend framework 有更好的方式,你可以很容易的去替换成 zend framework 。symfony 的例子意思是可靠性最好不要建立在 第三方基础上,而是自己有实现,也可替换成第三方实现。 因为我闭门造车,很多小的细节不可避免的有问题,目前就是希望能有一小撮人一起来讨论,做好。 |
20
dvaknheo OP @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 |
21
ruoge3s 2020-05-16 21:33:08 +08:00
# 20 楼那个,在构造器里加权限判断,耦合太严重了。😄
|
22
ruoge3s 2020-05-16 21:35:43 +08:00
1. 建议楼主可以多看看一看设计模式。
2. 自己写一些框架组件没什么问题的。有些东西自己写了,才会更能感受到别人写的一部分东西确实很优秀。借鉴人家优秀的东西,让自己的框架、组件更优秀,让自己更优秀吧。 |
23
dvaknheo OP @ruoge3s 控制器的构造器就是干这样的活的,还觉得耦合严重。。。
控制器又不需要继承系统基本类,一看就明白。 给你看个耦合严重的控制器例子吧。 ``` namespace App\Http\Controllers; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Routing\Controller as BaseController; class Controller extends BaseController { use AuthorizesRequests, DispatchesJobs, ValidatesRequests; } ``` 这时候,你就的去看 BaseController 里有什么,会影响到什么。 还有 AuthorizesRequests DispatchesJobs ValidatesRequests 都有什么功能。 似乎这些不管也无所谓。 控制器基本不会复用,复用的是 service,业务逻辑层。 keep it simple stupid. |
24
dvaknheo OP DuckPhp 1.2.3 到 1.2.4 版本有个显著改变是之前组件都没继承基类,实现什么接口。只使用 SingletonEx trait 做可变单例。
按 MyComponent::G()->init(array $optioins, $context=null): this; 这样的约定初始化(可以想象成 ServiceProvider. 1.2.4 之后,各组件使用 MyComponent extends DuckPhp\Core\ComponentBase , ComponentBase implements ComponentInterface,这样的方式,多了一个继承,内部实现一个接口。 实际上你编写扩展,也只需要满足约束 MyComponent::G()->init(array $options, $context=null): this; 就行了,没必要 实现 ComponentInterface 的所有接口 ComponentBase 帮你过滤你只需要的 $options 选项。 拆分 init() 为 initOptions($options) initContext() 两个空方法以便于你的继承。 以上这些,只是核心工程师需要了解的。应用工程师用不到。 影响应用工程师的是少量选项,方法名又因为名称不满意,细调了,不兼容了。 核心工程师有没有会被版本升级恶心的事呢? 有,继承系统类的时候,或许系统类的类型会调整成强类型,签名不同了。 最后,还可能会有什么问题呢? Helper 的函数名字冲突,比如你在旧版本的 Helper 加了个函数, 升级后函数名相同,但签名不同,这也是不太可能出现的情况。 |
25
beastk 2020-05-16 23:54:06 +08:00 via iPhone
其实我还在用 php5.2
|
26
jqh 2020-05-17 10:52:19 +08:00
@dvaknheo
不是说核心工程师造轮子,是核心工程师调轮子。应用工程师一个 DuckPhp 命名空间的东西也用不到。 DuckPhp 用 phpstan 检查过规范,phpunit 单元覆盖测试 100% 。 -------------------------------------------------------- “应用工程师一个 DuckPhp 命名空间的东西也用不到”,你这句话翻译一下就是:这个框架基本什么基础功能都不提供。 那你让“核心工程师”调什么?你有提供 HTTP 请求和响应处理功能有吗?配置文件功能有吗?文件处理功能有吗?缓存工具有吗?参数表单验证工具有吗?还有更多基础功能你都没有,那你怎么让“核心工程师”不造轮子? 最终的结果就是各种所谓的“核心工程师”拿到你的框架就是群魔乱舞各种瞎写,最后出来的就是惨不忍睹、很难维护的糟糕代码,这也是很多所谓自研框架公司的现状。 + blade 模板 违背了 PHP 代码就是视图的原则 + 滥用 ArrayIterator foreach, 使得没法 dump + orm 使得调试更麻烦了 + 退化到路由表了。有简单的文件路由不用。 + 中间件使得调用关系复杂化。 -------------------------------------------------------- PHP 代码是视图的原则??这都 2020 年了,您还崇尚 HTML 和 PHP 混编呢?这写出来的代码能维护?大清早就灭亡了亲; orm 使得调试更麻烦了,laravel 提供了多种方式可以让 ORM 转化成 sql 调试,调试虽然麻烦了一点,但 ORM 带来的便利程度远远大于麻烦程度; 退化到路由表了。有简单的文件路由不用,中间件使得调用关系复杂化,从这个描述就说明,你根本没理解 laravel 路由和中间件的好用之处。 中间件最大的好处就是能把各种与业务无直接关联的代码抽象出来,放在中间件里面,每个业务控制器 action 就可以通过配置轻松增减、切换各种不同的中间件,而不需要改动业务的一行代码。比如日志收集、登陆验证、接口权限判断等等,我甚至可以实现各种逻辑不同的登陆中间件,随意切换,如果你把这些跟业务无关的代码放在控制器中,那最终只会造成你代码杂乱、臃肿和难以维护。 那么 laravel 的路由结合中间件的配置,简直不要太好用,我可以轻松给各种路由进行分组;尤其是方便了开发者写扩展包,可以以最大的自由度定义扩展包路由,以及其实用的中间件,简直太牛逼了。其他的大部分框架,都没有这么好用的路由,也难怪 laravel 的生态如此强大,可以说 laravel 的高质量的第三包扩展包的数量可以吊打任何一款 PHP 框架。 可见一个成熟的设计是多么重要,细节和生态才是一个框架的根本。laravel 的方方面面的设计,其实都是兼顾了普通开发者和第三方扩展包开发者的需求的,但很可惜,很多人并不理解其中的意义。 而楼主说的中间件使得调用关系复杂化,这完全可以说是你的水平不够,中间件的配置入口就是公共配置和路由配置两种,能复杂到哪去?堆栈调用复杂?我宁愿看多几十行堆栈调用,也不愿写业务代码和与业务无关代码混杂在一起像乱麻一样的代码。 之前在我本机弄了 laravel 自带的 auth 的版本,发现 laravel auth 连我都没能弄清楚,怎么可能会有国内项目用他那套做验证 -------------------------------------------------------- 你这个把我看笑了,你是看不起其他程序员,还是太看得起自己?? laravel auth 你都整不明白,还好意思大言不惭说这个不行那个不行?建议楼主保持谦逊的态度,对不懂的东西不要乱评判,看了楼主的发帖纪录,就是一直在评判自己没搞懂的东西 |
27
dvaknheo OP @jqh
“应用工程师一个 DuckPhp 命名空间的东西也用不到”,你这句话翻译一下就是:这个框架基本什么基础功能都不提供。 ---- 是有这么一个基本用不到的功能:是你可以无缝替换成另一个框架。 翻译就是无耦合。 HTTP 请求, $_GET,$_POST 还没死绝呢。PHP 官方又没出一个自己的 psr 接口。PHP 为什么比 Java 容易明白没? Framework 和 Library 的区别知道么。 非得所有的都要要你 framework 里的么? 没关系,核心工程师怎么偷换实现都不会乱, 反正应用工程师看不到。 PHP 代码是视图的原则??这都 2020 年了,您还崇尚 HTML 和 PHP 混编呢?这写出来的代码能维护?大清早就灭亡了亲; 那么非 PHP 的视图模板里写 sql 你见过没。Widget 里一个超级对象你见过没。PHP 视图的原则是不做计算,只输出,而不是混编。 [Smarty 出了这么多年,PHPer 又退化到用 PHP 来写视图模板了] orm 使得调试更麻烦了,laravel 提供了多种方式可以让 ORM 转化成 sql 调试,调试虽然麻烦了一点,但 ORM 带来的便利程度远远大于麻烦程度; 调试是重要工作。而且 orm 需要多学一层,所以又过滤了一部分懒人。 PHP 最大的好处之一就是随时改业务代码。 DuckPhp 好处之一就是你可以把你的中间件做成独立的工程独立使用。应该说是可以把独立工程变成“中间件”,之前回答里都有了,我上面没演示的是 view 和 配置,也可以 重载。 DuckPhp 好处之二就是这些东西都是显式表达的,你不会看到“哇靠,这东西从哪里冒出来的,究竟错在哪里”。 如果你把业务代码放在控制器里,那等到 10k 行控制器的时候维护起来就痛苦死了。 日志收集,登陆验证,接口权限判断这些,都是核心工程师的职责。所以他们会告诉应用工程师:继承这个控制器基类就够了。想改这些,在基类里改就是。 我水平不够,所以只能用 PHP 这种语言。现在高水平的都去用 Java ,Go 了。 所以我写的框架也只是适用于那些想用 PHP 快速开发的人。 [Laravel 是很优雅的框架,不应该使用 PHP 这种不优雅的语言,应该使用更好的语言来写。] Laravel 默认的 auth 代码的流程我后来是弄清楚了。搞那么复杂的目的是为了有效的过滤智力低下的懒惰的 CURD 程序员。 |
28
nicoljiang 2020-05-17 11:39:34 +08:00
Laravel 是很优雅的框架,不应该使用 PHP 这种不优雅的语言,应该使用更好的语言来写。
+1 Laravel 的作者继续耕耘 .NET 方向多好 |
29
jqh 2020-05-17 12:37:47 +08:00
@dvaknheo
```php public function postLogin(Request $request) { $vaptcha = Vaptcha::make(); // 验证验证码是否正确 if (! $vaptcha->validate()) { // 验证不通过,返回错误提示信息到前端 return $this->error($vaptcha->getError()); } $credentials = $request->only([$this->username(), 'password']); $remember = (bool) $request->input('remember', false); // 验证参数 $validator = Validator::make($credentials, [ $this->username() => 'required', 'password' => 'required', ]); if ($validator->fails()) { return $this->validationErrorsResponse($validator); } // 登陆并返回成功信息 if ($this->guard()->attempt($credentials, $remember)) { return $this->sendLoginResponse($request); } // 返回失败信息 return $this->validationErrorsResponse([ $this->username() => $this->getFailedLoginMessage(), ]); } ``` 这里我截取一段使用 laravel auth 实现的登陆功能,换成你的说法,就是你口中“应用工程师”该写业务代码,多简洁易懂,这代码不好维护吗?跟业务无关吗? 而其中$this->guard()->attempt 这样的 auth 底层实现,就是你口中“核心工程师”写的登陆的轮子,框架内置的轮子不比大部分“核心”工程师写的优质、好用许多吗? laravel 这样设计的更强大之处在于,“应用工程师”甚至不必关心登陆验证的数据存储细节,例如你是想使用 session 登陆、还是 auth2.0 登陆、还是缓存 token 之类的等等,都可以通过配置文件和中间件随意切换,不需要改动一行业务代码,这不是更简单了吗?而登陆到底是要用 session 还是 auth2,这个可以交给“核心工程师”去实现。 而且不仅如此,laravel 的几乎所有组件都是这样的模式,系统把大部分功能都抽象成了一个统一的简单易用的功能接口,“应用工程师”写业务代码并不需要关心这些功能的具体实现,只需要简单的调用数行代码就行,可以把专注点放在业务上,而这些底层组件可以采用第三方扩展包也可以由“核心工程师”自己编写,然后通过配置文件切换而不用影响业务代码。 你所考虑的,laravel 早就想到了。 |
30
dvaknheo OP @jqh 这是一个例子恰好演示了其糟糕性。
单是返回就有四种可能 return $this->error($vaptcha->getError()); return $this->validationErrorsResponse($validator); return $this->sendLoginResponse($request); return $this->validationErrorsResponse([$this->username() => $this->getFailedLoginMessage(),]); 而且注意到的是,按常理,最后一个才是正常返回。取反放最后就是。 但是这样还没完。 validationErrorsResponse 接受的参数又是 Validator ,又是 array 。还好 php 是弱类型。 可是 $this->getFailedLoginMessage() 又从哪里来? 是否前面的调用会影响状态。 $this->guard()->attempt($credentials, $remember) 这个 guard() 也是怎么冒出来的,为什么要和控制器耦合,这个 attepm 词也很少见。 为什么不是 this->attempt($credentials, $remember) 下面是我重构的结果。 ``` class MyController { public function postLogin(Request $request) { // 输入处理,放前面,不必节省性能。 $remember = (bool) $request->input('remember', false); $credentials = $request->only([$key_username, 'password']); //这也算输入吧 $key_username= $this->username(); //验证码服务 $error = VaptchaService::make()->validate(); if ($error) { // 验证不通过 return $this->error($error); } //兼容,如果 service 有方式获得这个 $guard,则不需要输入。 $guard = $this->guard(); //登录服务 $error = LoginService::make()->login($guard,$key_username,$credentials,$remeber); if($error){ if(is_array($error)){ $error[$key_username] = $this->getFailedLoginMessage(); } return $this->validationErrorsResponse($error); } return $this->sendLoginResponse($request); } } class VaptchaService { // 省略 make 静态方法。 public function validate() { // 验证验证码是否正确 if (! Vaptcha::make()->validate()) { return $vaptcha->getError(); } return null; } } class LoginService { // 省略 make 静态方法 public function login($guard,$key_username,$credentials,$remember) { // 验证参数 $validator = Validator::make($credentials, [ $key_username => 'required', 'password' => 'required', ]); if ($validator->fails()) { return $validator; } // 登录验证 $flag=$guard->attempt($credentials, $remember); if (!$flag) { return [ $key_username => "something wrong"]; } return null; } } ``` 如果使用 DuckPhp 你大概会这么写。 ``` class MyController { // 登录页面 public function login() { C::Show([],'login'); } //处理 post public function do_login() { // 输入处理,放前面,不必节省性能。 $remember = (bool) C::POST('remember', false); $credentials = C::SG()->_POST(); $error=null; try{ //验证码服务 VaptchaService::G()->validate(); //登录服务,返回用户信息。 $info = LoginService::G()->login($credentials,$remeber); //保存 session 数据 SessionService::G()->setLoginUserInfo($info); C::Show(get_defined_vars(),'login-done'); }catch(\Throwable $ex){ $error = $ex->getMessage(); C::Show(get_defined_vars(),'login'); } } } ``` 为什么要调 3 个服务解决问题,而不是一个, 第一个是处理验证码的,和 web 平台有关的特殊服务 第二个是主要业务,测试的时候,可以命令行运行,获得信息,不必通过 web 第三个是 session 系统管理,管控所有 session 系统,也是和 web 平台有关的特殊服务 |
31
jqh 2020-05-17 14:39:34 +08:00
@dvaknheo 你暴露了,就凭你不知道 guard 和 attempt 方法还说自己弄懂了 laravel auth....,guard 和 attempt 就是 auth 的组成部分。
|
32
jqh 2020-05-17 14:42:29 +08:00
return $this->error($vaptcha->getError());
return $this->validationErrorsResponse($validator); return $this->sendLoginResponse($request); return $this->validationErrorsResponse([$this->username() => $this->getFailedLoginMessage(),]); 这些只是响应数据的方法,没必要展示出来而已。 而你这些 service 只是业务代码的结构约定划分,跟框架没有半毛钱关系,我如果愿意也可以这样划分。而你这个 sessionservice 就是画蛇添足,使用了 laravel auth,业务层根本不必关心登陆验证是要使用 session 还是 token,这些根本不必跟业务代码耦合。 |
33
dvaknheo OP @jqh 问题是为什么一个简单的登录,会搞出那么多东西出来? 真的会有人重写这个 guard 的实现么?
控制器的 $this->guard() 要查找多少代码理解。这也就是 Laravel 不能用 类名 /方法 文件路由的原因。 我刚才查了手头的 laravel 6 的 例子,没找到你这段代码,不知道你这是 laravel 几的版本。 业务层必须能用命令行运行,最好是无状态的。Web 控制器层不做业务。 控制器不能 dump 起来一堆方法都不知道干什么的。 不要指望应用工程师通读了 Illuminate\Auth 和 Illuminate\Foundation\Auth 之后才开始工作。 |
34
love51money 2020-05-18 08:55:14 +08:00
关注。楼主辛苦。
|
35
yxn1910 2020-05-18 10:02:17 +08:00
我一直有个很巨大的疑问,都已经用上 laravel 的人,相比于直接上 spring boot 有哪些非用不可的理由?
1.相较其他框架更大开发效率? 2.相较其他框架更快代码执行效率? 3.巨大的投入产出比? 4.投入时间进行学习后更利于找到工作? 5.更加优雅? |
36
DavidNineRoc 2020-05-18 11:39:50 +08:00
@yxn1910
你说的都没用,最直接的公司用 PHP |
39
iidestiny 2020-05-21 10:09:17 +08:00
还是给楼主一个赞,坚持自己。
|
40
dvaknheo OP @iidestiny 我是 CodeIgniter 出身的,
一条原则就是,能不使用系统自带的就不用系统自带的。 也就是我的想法:框架只做最少的事情。 CodeIgniter 的优点是你不会怕:这东西哪里来的。 缺点嘛,太多了没必要说了。 TP 我用得不如 Laravel 多。但 Laravel 没有我能感觉到的优点 如果说有,那就是有人说的,现在给 laravel 做的第三方包比较多。 拿来就用,不必关心细节。 而之前 TP 之类,都是给项目而不能直接使用。 DuckPhp 一个卖点就是你可以直接把你的项目做为第三方包。 laravel 的 auth 真的很差啊 而且我不认为 auth 这些东西应该放在默认的框架里。 其他框架的用户系统 demo 都很容易懂,很容易改。 laravel 的用户系统 demo 是你们水平不够不要改。 |