考虑此类安排-特别是魔术函数__invoke:
class Barman {
public function __construct() {
// .. .constructor stuff - whatever
}
public function makeDrink() {
return "vodka martini, shaken";
}
}
class Bar {
private $arr_barmen = array();
public function __construct() {
$this->arr_barmen['john'] = new Barman();
}
public function __invoke($barman_id) {
echo "I have been invoked";
return $this->arr_barmen[$barman_id];
}
public function aBarFunc($param) {
return "yes it worked ," .$param;
}
}
class Foo {
public $myBar;
public function __construct() {
$this->myBar = new Bar();
}
}
我想写这样的语法
$company = new Foo();
$company->myBar('john')->makeDrink();
首选结果: “伏特加马提尼酒,动摇了”
实际结果:
“调用未定义的方法Foo :: myBar()”
使用magic方法调用myBar()应该会返回一个酒保对象,您可以在其上调用任何酒保的公共方法
但是现在考虑一下(确实有效)
$company = new Foo();
$myBar = $company->myBar;
$drink = $myBar('john')->makeDrink();
echo $drink;
// Result:
// I have been invoked
// vodka martini, shaken
那是怎么回事?我不喜欢这种解决方法-它不时尚。 我需要它以这种方式工作:
$ company-> myBar('john')-> makeDrink();
请帮助? :-)
答案 0 :(得分:1)
要获得链接,必须在调用中返回Barman对象。
class Barman {
public function __construct() {
// .. .constructor stuff - whatever
}
public function makeDrink() {
return "vodka martini, shaken";
}
}
class Bar {
private $arr_barmen = array();
public function __construct() {
$this->arr_barmen['john'] = new Barman();
}
public function __invoke($barman_id) {
echo "I have been invoked";
return $this->arr_barmen[$barman_id] = new Barman();
}
public function aBarFunc($param) {
return "yes it worked ," . $param;
}
}
class Foo {
public $myBar;
public function __construct() {
$this->myBar = new Bar();
}
// create a function with variable name to invoke the object
public function myBar($name) {
$mybar = $this->myBar;
return $mybar($name);
}
}
答案 1 :(得分:1)
这是由您要拨打的电话中的模棱两可引起的:
$company->myBar('john')->makeDrink();
由于myBar
是一个属性,因此PHP解释器不希望它可被调用。它将其解析为试图调用不存在的称为myBar()
的方法,从而引发了错误。
解决此问题的直接方法是澄清解释器的歧义。为此,请在属性周围添加花括号,如下所示:
$company->{myBar}('john')->makeDrink();
现在,该代码已明确表明myBar
是一个属性,应按原样进行访问,但是它包含一个可调用的值,并且您希望进行该调用。
由于PHP 5.x和PHP 7.x在默认情况下如何处理此类歧义,因此它们的行为有所不同,这使整个主题变得(略有复杂)。 PHP 7更改了默认值,以纠正该语言中的一些内部不一致之处。结果是,在这种情况下,如果您想让代码在PHP 5.x和7.x上都可以使用,则应该始终使用大括号来明确定义希望其工作的方式,无论如果没有它们,您的代码是否对您有用。
the PHP 7.0 upgrade notes中有一些有关此更改的文档,尽管给出的示例并未涵盖您的确切情况。
答案 2 :(得分:0)
感谢您的回复。我设计了一个可爱的解决方法,如下所示:
class Barman {
public function __construct() {
}
public function makeDrink() {
return "vodka martini, shaken";
}
}
class Bar {
private $arr_barmen = array();
public function __construct() {
$this->arr_barmen['john'] = new Barman();
}
public function getBarman($barman_id) {
return $this->arr_barmen[$barman_id];
}
public function __invoke($barman_id) {
echo "I have been invoked \n";
return $this->arr_barmen[$barman_id];
}
}
class Foo {
private $_myBar;
public function __construct() {
$this->_myBar = new Bar();
}
// The fix
public function myBar($barman_id) {
return $this->_myBar->getBarman($barman_id);
}
}
用法:
$company = new Foo();
$drink = $company->myBar('john')->makeDrink();
echo $drink; // vodka martini, shaken
它如何工作? Foo-> myBar变为私有(Foo-> $ _ myBar);
我们在Foo中创建一个名为myBar的公共函数;
我们在Bar内部创建一个“ getBarman”功能,从Foo-> myBar('john')调用
还有几个步骤-现在没有歧义-Foo-> myBar()始终是一个函数。
欢呼
M
答案 3 :(得分:0)
我相信您可以在其周围加上括号:
$company = new Foo();
$drink = ($company->myBar)('john')->makeDrink();
echo $drink; // vodka martini, shaken