2

我有一些困惑!我有一个简单的类,如下所示

class MyClass {
    public $bar;
}

然后我做了一个实例

$cls = new MyClass;

然后我$bar从课堂外为我的公共财产分配了价值

$cls->bar='Bar';

然后我添加了新的公共属性$baz并从类外为其赋值

$cls->baz='Baz';

然后我添加了一个新的公共属性$showBar并从类外部为其分配了值,这次值是一个匿名函数

$cls->showBar = function(){
    return $this->bar;
};

然后我转储了$cls使用var_dump($cls);实例,输出是

object(MyClass)[10]
  public 'bar' => string 'Bar' (length=3)
  public 'baz' => string 'Baz' (length=3)
  public 'showBar' => 
    object(Closure)[11]

似乎我添加的所有公共属性都可用,包括该anonymous功能,然后我已经完成了

echo $cls->bar; // Bar
echo $cls->baz; // Baz
echo $cls->showBar(); // error

公共属性showbar在类中可用(var_dump 显示它)但是当我调用它说的函数时

致命错误:在第 234 行的 D:\xampp\htdocs\phpTutorialInfo\bind\bindtoCls.php 中调用未定义的方法 MyClass::showBar()

问题是:可以在初始化后添加新属性(使用标量值可以正常工作)并且showbar似乎可用,那么为什么无法Php识别它,如果是因为它的值是一个匿名函数,那么为什么它在var_dump输出中可用包括函数本身以及为什么Php让我分配值(匿名函数),当我尝试分配属性的值时它应该抛出错误showbar?这有可能吗?

4

3 回答 3

4

您不能以这种方式调用该函数。那是因为 PHP 允许在一个类中拥有变量和具有相同名称的函数。如果您使用函数运算符,()PHP 将只查看函数列表,而不查看作为闭包的变量。

从 PHP5.4 开始,解决方案可能如下所示:

class MyClass {

    public function __call($fname, $args) {
        // bind the `this` scope to use
        $cl = $this->{$fname}->bindTo($this);
        // call the function and pass args to it
        return call_user_func_array($cl, $args);
    }

}

例子:

$obj = new MyClass();
$obj->func = function() {
    echo 'We are in ' . get_class($this);
};

$obj->func(); // We are in MyClass

你可以在这里测试

于 2013-07-01T19:38:42.117 回答
3

您不能在 PHP 中动态添加方法。您所做的是添加一个自定义属性,这是一个函数。但这并不能使它成为一种方法。为了说明差异,您可以创建一个具有相同名称的属性和方法的类:

class A {
    public $test = 42;
    public test() { return 43; }
}

$a = new A;
$a->test === 42;
$a->test() === 43;
于 2013-07-01T19:44:22.317 回答
2

您可以使用call_user_func. 例子:

<?php
class MyClass {
    public $bar;
}
$cls = new MyClass;
$cls->bar='Bar';
$cls->baz='Baz';
$cls->showBar = function() use ($cls) {
    return $cls->bar;
};

echo call_user_func($cls->showBar); // Bar
?>

您可能想要定义__call魔术方法,以便可以return $this->bar代替传递$cls闭包。

于 2013-07-01T19:41:49.630 回答