V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  dvaknheo  ›  全部回复第 8 页 / 共 14 页
回复总数  270
1  2  3  4  5  6  7  8  9  10 ... 14  
2020-04-14 21:33:08 +08:00
回复了 dvaknheo 创建的主题 PHP [吐槽]刚读了 yii3-demo, PHP 框架是怎么把 PHP (优雅的)玩死的。
@JohnH Laravel 命名空间我也在用。
laravel 我用过,yii1 有个好产品,一直没看下去。yii2 看了一些没写,然后看看 yii3 所以由此感慨。

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

当初各项目都赶时髦用 Smarty 。我就有这个问题:解决了什么问题? 模板还是要程序员来写。
2020-04-14 21:08:08 +08:00
回复了 dvaknheo 创建的主题 PHP [吐槽]刚读了 yii3-demo, PHP 框架是怎么把 PHP (优雅的)玩死的。
@hantsy slim 只是个路由映射。连 url 函数都没有。写 rest 或许会方便些。
印象深刻的是 slim 里那个正则。

同一作者写的 phpparser 不错。
2020-04-14 21:04:41 +08:00
回复了 dvaknheo 创建的主题 PHP [吐槽]刚读了 yii3-demo, PHP 框架是怎么把 PHP (优雅的)玩死的。
@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 过程中,我经常想的是:不这么做不行么?只有不得已才加上必要的功能。
2020-04-14 20:07:28 +08:00
回复了 dvaknheo 创建的主题 PHP [吐槽]刚读了 yii3-demo, PHP 框架是怎么把 PHP (优雅的)玩死的。
@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 兼容的插件, 把初始化部分放在主流程, 运行部分在工作协程。无需改动代码。
2020-04-14 19:01:22 +08:00
回复了 dvaknheo 创建的主题 PHP [吐槽]刚读了 yii3-demo, PHP 框架是怎么把 PHP (优雅的)玩死的。
比如内置了 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 开发相同功能是怎么做的,代码能少多少了。
2020-04-14 18:50:25 +08:00
回复了 dvaknheo 创建的主题 PHP [吐槽]刚读了 yii3-demo, PHP 框架是怎么把 PHP (优雅的)玩死的。
@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 的 堆栈根不同。
2020-04-14 18:43:06 +08:00
回复了 dvaknheo 创建的主题 PHP [吐槽]刚读了 yii3-demo, PHP 框架是怎么把 PHP (优雅的)玩死的。
@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-> 后去看这东西是不是父类里冒出来的。
而且也告诉你, 你的工程继承可以父类。
2020-04-14 18:13:16 +08:00
回复了 taaaang 创建的主题 PHP PHP 的 sql 到底该写在哪儿?
Service/Logic 跟业务走。
Model/Repository 跟表走 如果是附属表也可以不那么严格。

比如用户充值,需要修改余额和生成充值记录,那么直接用$user->recharge($money)我觉得是比较方便和复用的,那么对我来说就是适合的,

按业务来分的话
UserService::Recharge($user_id,$money)
这个走 RechargeModel 还可能要用到 LogModel 还看看用户是否有钱 UserInfoModel
UserService::GetProfile($user_id)
用 UserInfoModel
2020-04-14 12:18:23 +08:00
回复了 dvaknheo 创建的主题 PHP [吐槽]刚读了 yii3-demo, PHP 框架是怎么把 PHP (优雅的)玩死的。
@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 就是。
2020-04-14 12:04:45 +08:00
回复了 dvaknheo 创建的主题 PHP [吐槽]刚读了 yii3-demo, PHP 框架是怎么把 PHP (优雅的)玩死的。
@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 开发氛围。
2020-04-14 11:33:00 +08:00
回复了 dvaknheo 创建的主题 PHP [吐槽]刚读了 yii3-demo, PHP 框架是怎么把 PHP (优雅的)玩死的。
@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;
}
```
这样不清晰么。
--
希望别超过长度
2020-04-13 17:26:50 +08:00
回复了 dvaknheo 创建的主题 PHP [吐槽]刚读了 yii3-demo, PHP 框架是怎么把 PHP (优雅的)玩死的。
@jhdxr
没看过 yii3-demo,但是在 laravel 里至少这么做并没有被推荐?我印象中看过的大部分都还是会分一个 repository 出来

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

一个业务逻辑,可能要由 多个 repository 完成。 得到的 结果数组,输出给 view 。view 里基本不做计算。 因为 view 也得由 php 程序员来改,smarty 这类的模板,还是得由 php 程序员来改。没必要那么折腾。
2020-04-05 21:14:32 +08:00
回复了 pinews 创建的主题 程序员 互联网 ipv4 v6 new ip 我的看法
都什么年代了,电话都可以点对点,IP 网还不能点对点。
2020-04-04 20:35:41 +08:00
回复了 monkeyWie 创建的主题 程序员 技术博客真就套娃啊
也就是我要写推广的话,挂几个知名站点让他们爬就行了?

嗯,好办法。

DuckPHP 这个 web 框架看来能这么推广 (逃
2020-04-02 20:59:32 +08:00
回复了 dvaknheo 创建的主题 PHP DuckPHP 1.2.3 发布,属临时性发布
@king888

一, 入口类 DuckPhp\App 在 init() 开始阶段就替换成项目的 MY\Base\App extends DuckPhp\App 执行后续操作。 你可以在 MY\Base\App 里随便改实现。

二,可变单例,Duckphp 的组件都是用 G($object) 方法调用。你可以传入新的继承旧组件的类。

比如,My\Helper\ControllerHelper::GET() 调用的是 DuckPHP\App::GET() 返回 SuperGlobal::G()->_GET 。
你可以重写 My\Base\App::onInit(); 追加一个 My\SuperGlobal extends SuperGlobal 支持 workerman 或 swoole

更常出现的是 App::Pager(My\Base\Pager::G()); 自己 重写 Pager 类实现自己的渲染。 调用还是 echo C::PageHtml();
2020-04-02 09:05:24 +08:00
回复了 dvaknheo 创建的主题 PHP DuckPHP 1.2.3 发布,属临时性发布
@praming 这框架两个特点
一是可以热修复, 所有东西都可以替换成你实现的版本,所以如果有漏洞了,第一时间是修改工程中的实现,而不用更新框架版本。 所有不满足这个特性的框架,都是不值得看的。

二是只有工程的几个核心文件才和框架文件相关联。替换成其他东西很容易,尽管这基本不用。

其他巧妙之处,我需要人来重新描述一下。给其他人方便理解。
2020-04-01 22:54:35 +08:00
回复了 SlipStupig 创建的主题 程序员 50 岁以后的程序员还能找到工作嘛
为什么老板会要一个 35 的程序员呢?
2020-04-01 22:13:01 +08:00
回复了 MuscleOf2016 创建的主题 职场话题 如何看待,工作中聊天工具,半天不回复信息?
回 收到,表示已经看到这条消息,可能有其他手上工作。
回 收到,正在处理,才是处理问题中
2020-04-01 21:12:01 +08:00
回复了 dvaknheo 创建的主题 PHP DuckPHP 1.2.3 发布,属临时性发布
@panxianhai 我个人很感慨 laravel 的推广能力,但同时不喜欢 laravel 把 php 搞得那么复杂。

比如中间件系统, 搞得堆栈几乎没法看。我的解决方案,如果是普通程序,在 控制器 的构造和析构方法里解决就行了。再上一级的,就是用路由钩子前后钩挂,再上一级,那就是重写 run 方法。

控制器里写的,也就是普通代码人员的级别,一看就能看出来
再往上,钩子的级别,特殊的控制。这是小组长的干活。
重写 run 方法,除非是很特殊很特殊,才有意义。

调试程序,最怕之一就是:我明明这么写了,但是为什么代码没跑到这里,怎么调试。


blade 模板,这玩意让我想起了当年 smarty,写模板的还是 php 人员来写。我不认为模板引擎是框架的必备部分。

我以前写过一个模板引擎叫 TagFeather 。上个月想复活,然后发现那玩意当年写得太复杂了,没足够动力搞定。
人家是解析字符串方式解析模板, 我是解析 XML,而且是允许带 php 标记的 xml 。
那么这个模板引擎有什么好处呢? 静态 html 页面 + php 大纲页面 编译成最终 可读的 php 页面,用 jquery 选择器方式关联。
2020-03-29 21:47:49 +08:00
回复了 wework 创建的主题 程序员 谷歌浏览器竟然自带 lazy load API
看了一下我的谷歌浏览器:

版本 43.0.2357.81 m

不知道哪一年的版本
1  2  3  4  5  6  7  8  9  10 ... 14  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3360 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 22ms · UTC 10:46 · PVG 18:46 · LAX 02:46 · JFK 05:46
Developed with CodeLauncher
♥ Do have faith in what you're doing.