mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-21 00:54:53 +08:00
Fixes controller DI
This commit is contained in:
@@ -73,6 +73,12 @@ class Controller extends \yii\base\Controller
|
|||||||
$name = $param->getName();
|
$name = $param->getName();
|
||||||
if (($class = $param->getClass()) !== null) {
|
if (($class = $param->getClass()) !== null) {
|
||||||
$className = $class->getName();
|
$className = $class->getName();
|
||||||
|
}
|
||||||
|
// We only enter the class injection code path if:
|
||||||
|
// - A class is hinted in the method signature
|
||||||
|
// - And the param name of hinted class does not exist in existing $params, or the value in existing $params is not an instance of the hinted class
|
||||||
|
// The latter two checks allow us to manually inject classes via $params while ignoring wrongly injected values (no instances of hinted class).
|
||||||
|
if ($class !== null && (!array_key_exists($name, $params) || !$params[$name] instanceof $className)) {
|
||||||
if (Yii::$app->has($name) && ($obj = Yii::$app->get($name)) instanceof $className) {
|
if (Yii::$app->has($name) && ($obj = Yii::$app->get($name)) instanceof $className) {
|
||||||
$args[] = $actionParams[$name] = $obj;
|
$args[] = $actionParams[$name] = $obj;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -77,5 +77,18 @@ class ControllerTest extends TestCase
|
|||||||
|
|
||||||
$result = $controller->runAction('aksi6', $params);
|
$result = $controller->runAction('aksi6', $params);
|
||||||
$this->assertEquals(['d426', false, true], $result);
|
$this->assertEquals(['d426', false, true], $result);
|
||||||
|
|
||||||
|
// Manually inject an instance of \StdClass
|
||||||
|
// In this case we don't want a newly created instance, but use the existing one
|
||||||
|
$stdClass = new \StdClass;
|
||||||
|
$stdClass->test = 'dummy';
|
||||||
|
$result = $controller->runAction('aksi7', array_merge($params, ['validator' => $stdClass]));
|
||||||
|
$this->assertEquals(['d426', 'dummy'], $result);
|
||||||
|
|
||||||
|
// Manually inject a string instead of an instance of \StdClass
|
||||||
|
// Since this is wrong usage, we expect a new instance of the type hinted \StdClass anyway
|
||||||
|
$stdClass = 'string';
|
||||||
|
$result = $controller->runAction('aksi8', array_merge($params, ['validator' => $stdClass]));
|
||||||
|
$this->assertEquals(['d426', 'object'], $result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,4 +46,14 @@ class FakeController extends Controller
|
|||||||
{
|
{
|
||||||
return [$q, $validator->validate($q), $validator->validate('misbahuldmunir@gmail.com')];
|
return [$q, $validator->validate($q), $validator->validate('misbahuldmunir@gmail.com')];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function actionAksi7($q, \StdClass $validator)
|
||||||
|
{
|
||||||
|
return [$q, $validator->test];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function actionAksi8($q, \StdClass $validator)
|
||||||
|
{
|
||||||
|
return [$q, gettype($validator)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user