Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP Magic _;在类的对象属性上调用_Php_Class_Invoke_Magic Methods_Chainability - Fatal编程技术网

PHP Magic _;在类的对象属性上调用

PHP Magic _;在类的对象属性上调用,php,class,invoke,magic-methods,chainability,Php,Class,Invoke,Magic Methods,Chainability,考虑这个类的安排,特别是神奇的函数调用: class Barman { public function __construct() { // .. .constructor stuff - whatever } public function makeDrink() { return "vodka martini, shaken"; } } class Bar { private $arr_barmen =

考虑这个类的安排,特别是神奇的函数调用:

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()应该返回一个barman对象,您可以在该对象上调用barman的任何公共方法

但是现在考虑这个(确实有用)< /P> 发生了什么事?我不喜欢那种变通方法——它不光滑。 我需要它以这种方式工作:

$company->myBar('john')->makeDrink()


请帮忙?:-)

要获得链接,必须在invoke中返回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);
    }

}

这是由您试图拨打的电话中的歧义引起的:

$company->myBar('john')->makeDrink();
因为
myBar
是一个属性,PHP解释器不希望它是可调用的。它正在解析它,试图调用一个名为
myBar()
的方法,该方法不存在,因此抛出错误

解决这一问题的直接方法是为口译员澄清歧义。可以通过在属性周围添加大括号来完成此操作,如下所示:

$company->{myBar}('john')->makeDrink();
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);
    }
}
代码现在明确表示,
myBar
是一个属性,应该这样访问,但它包含一个可调用的值,并且您希望进行该调用

由于PHP5.x和PHP7.x在默认情况下处理此类歧义的方式不同,整个主题变得复杂(稍微复杂)。PHP7更改了默认值,以纠正语言内部的一些不一致。其结果是,在这样的情况下,如果您想让代码在PHP5.x和7.x之间工作,那么应该始终使用大括号来明确定义它的工作方式,而不管没有大括号的代码是否适用于您


虽然给出的示例没有涵盖您的具体情况,但有一些文档说明了中的此更改。

感谢您的回复。我设计了一个可爱的解决方案,如下所示:

$company->{myBar}('john')->makeDrink();
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->$\u myBar)

我们在Foo中创建了一个名为myBar的公共函数

我们在酒吧里创建了一个“getBarman”函数,这个函数从Foo->myBar('john')调用

再多几个步骤——现在没有歧义了——Foo->myBar()始终是一个函数

干杯


M

我相信你可以在它周围加上大括号:

$company = new Foo();
$drink = ($company->myBar)('john')->makeDrink();
echo $drink; // vodka martini, shaken

你能澄清一下你使用的是什么PHP版本吗?\(这与此相关)。PHP7.2在这种情况下你是正确的,这是他将遇到的下一个问题。然而,他遇到的错误是试图访问
myBar
属性;ie在它尝试执行
\uu invoke()
调用之前抛出错误。是的,正确,这就是为什么创建了一个具有相同名称(属性)的函数。感谢@Harish的响应。不幸的是,这并不能解决这个问题,因为“return$this->arr_barman[$barman_id]=new barman();”只是覆盖了以前由myBar构造函数创建的barman。