【发布时间】:2021-06-19 15:31:51
【问题描述】:
有一个Controller 类包含神奇的__call() 方法,该方法在传递参数时获取名称并创建相应名称的实例。将Controller 类的属性$this 传递给该类的构造函数,以便使用req() 函数。
例如,我使用 3 个类的示例重新创建了生产环境中的情况。
class One
{
public function __construct(
protected Controller $controller
) {}
public function oneTestFunc(): void {
echo $this->controller->req([__FUNCTION__, __CLASS__]);
}
}
class Two
{
public function __construct(
protected Controller $controller
) {}
public function twoTestFunc(): void {
echo $this->controller->req([__FUNCTION__, __CLASS__]);
}
}
在PHPDoc中,我已经定义了可以调用的方法。
/**
* Class Controller
* @method One one()
* @method Two two()
*/
class Controller
{
public function __call(string $name, array $args): mixed {
$name = ucfirst($name);
return new $name($this);
}
public function req(array $data): string {
return sprintf("Call function %s (class: %s)\n", ...$data);
}
}
这一切都是正确的。但是,在创建类的实例时,您可以调用req() 函数,这仅在 PHPDoc 中预定义的类中允许。
好:
$x = new Controller();
$x->one()->oneTestFunc(); // Good: Call function oneTestFunc (class: One)
$x->two()->twoTestFunc(); // Cood: Call function twoTestFunc (class: Two)
// Unacceptable! Not directly possible, the req() function is only for predefined classes.
$x->req(['click', 'clack']);
问:如何避免这种情况?为此创建一个特征以在预定义的类中使用,或者对Controller 类进行包装,并已经从它继承?同志们,在这种情况下你有什么建议?
【问题讨论】:
-
P.S.
req()函数是对 http 请求的模仿。