我的英文水平有限,是不可能用英文来表达出我的意思的,所以请原谅我写下的中文。
我是一名中国的 yii 使用者和关注者。
我个人比较喜欢 yii,所以冒昧地写下这个 issue。
我结合我的使用情况,说说我的看法,以及提出几点改进建议。
<?php
namespace allowing\test\controller;
use yii\web\Controller;
class SiteController extends Controller
{
public function actionIndex(\yii\web\Request $request)
{
// 这样可以轻松访问到 \yii\web\Request 的实例
print_r($request->requestParams);
}
}
因为我觉得这样的做法,在实际开发中是很方便的,虽然 \Yii::$app->request
能轻松访问到 \yii\web\Request
实例,但是 \Yii::$app
的侵入性太强了。我和我的朋友们也这样讨论过。
暂时只想到这一点。感谢。
translated from Chinese:
He suggests to inject Yii::$app->request as first parameter in the Action parameter binding.
I kinda agree on this one. Magic like argument injection looks nice at first hand, but from an inheritance perspective you will encouter issues on long term. Its way more comfortable to have the full $request object available with typehinting & POST information. Of course this is BC break, but this definately is something to discuss for future releases. If you'd ask me, I would go for less magic and more OO.
This is how it works in Django. request
is a first parameter of action (it's called view
according to their terms). I think doing this for request
only doesn't make much sense. In this case components like user
(Yii::$app->user
) also should be refactored. In Django user
belongs to request
and can be accessed as request.user
. Yii has its own philosophy and I think developers have spent enough time to think and create application architechture what they think is right. I guess OP came from Django or framework with similar approach to write controller actions and it's uncomfortable to him to write the code in different way. You need to adapt to framework principles and philosophy you are using.
Again, this is not bad idea, but doing it for request only doesn't make much sense in my opinion.
Sounds like PSR-7.
I like the approach of Django
在实际的使用中,\Yii::$app->request
这样访问实例是真的不方便,如果多处需要这个实例一般还要赋值给一个变量,比如像下面这样:
<?php
namespace allowing\test\controller;
use Yii;
use yii\web\Controller;
class SiteController extends Controller
{
public function actionIndex()
{
// 要赋值给一个变量,才方便多处使用
$request = Yii::$app->request;
$request->get('name');
$request->get('age');
$request->get('page');
// 这样感觉怪怪的
Yii::$app->request->get('name');
Yii::$app->request->get('age');
Yii::$app->request->get('page');
}
}
要是能像这样就不同了,你会发现简洁很多:
<?php
namespace allowing\test\controller;
use yii\web\Controller;
use yii\web\Request;
class SiteController extends Controller
{
public function actionIndex(Request $request)
{
$request->get('name');
$request->get('age');
$request->get('page');
}
}
Right? 其实,方便使用也是一种程序设计该考虑的事情。
yes. We are talking about the same thing.
虽然在控制器的构造器里能实现自动注入,我现在就是这样使用的。
首先在入口脚本 index.php
里注册一个单例:
Yii::$container->setSingleton(\yii\web\Request::class);
Yii::$container->setSingleton(\yii\web\Response::class);
然后我再在我的控制器的构造器里声明依赖:
class SiteController extends Controller
{
private $_request;
public function __construct($id, $module, Request $request, array $config = [])
{
$this->_request = $request;
parent::__construct($id, $module, $config);
}
public function actionIndex()
{
// 这样我就可以使用了
$this->_request->get('foo');
}
}
^_^ ,感觉这样使用挺方便。所以今天才来提建议的。
Yes. It is handy.
@allowing 兄弟,你觉得自己的中文让老外看懂了吗?(Foreigners understand what you say Chinese?)^_^
Automatic Injection required
Sorry for using Chinese to submit this issue. My English is not very well so that I can't describe my problems clearly.
I'm a Chinese developer using yii, and I'm really enjoy developing things with it.
Now I have some suggestions to you.
I hope it is possible to let yii inject dependance automatically.
_like Laravel (added by translator)_
For example
<?php
namespace allowing\test\controller;
use yii\web\Controller;
class SiteController extends Controller
{
public function actionIndex(\yii\web\Request $request)
{
print_r($request->requestParams);
}
}
Thank you.
for people struggling with those impressive chinese symbols. These are actually quite easy to process in Google Chromes page translation tool. Right mouse -> translate to English.
in my project,I use some behaviors to deal with this problem
for example, In a controller ,
class TestController extend Controller
{
public $user;
public function behaviors()
{
return [
[
'class' => AuthFilter::className(),
],
];
}
}
and in the AuthFilter
if ($action->controller->canSetProperty('user')) {
$action->controller->user = $user;
}
if you have declare a $user property in your controller, you will get the $user instance by $this->user; look like some kind of auto inject.
no no no.....
你这个毕竟不是真正利用反射自动注入所需实例,这样存在强耦合。
其实很多时候,类的方法都不是我们自己手动调用的,都是框架回调的,比如控制器方法,既然是回调方法,就可以好好利用反射技术。
You're talking about auto-wiring of dependencies for controller method calls. Here it is: https://github.com/yiisoft/yii2/issues/9476
Most helpful comment
Here's the translation for the issue
Title
Automatic Injection required
Body
Sorry for using Chinese to submit this issue. My English is not very well so that I can't describe my problems clearly.
I'm a Chinese developer using yii, and I'm really enjoy developing things with it.
Now I have some suggestions to you.
I hope it is possible to let yii inject dependance automatically.
_like Laravel (added by translator)_
For example
Thank you.