如何从动态添加的函数中引用构造变量

时间:2016-10-16 15:18:43

标签: php class

如何重写以下内容......

class crunch {

    private $funcs = [];

    public function set($name, $function) {
        $this->funcs[$name] = $function;
    }

    public function call($function, $data=false) {
        if (isset($this->funcs[$function]) && is_callable($this->funcs[$function])) {
            return $this->funcs[$function]($data);
        }
    }
}

$db = 'dbhandle';

$crunch = new crunch();

$crunch->set('myfunction', function($data) {
    global $db;
    echo 'db = '. $db .'<br>'. json_encode( $data );
});

$crunch->call('myfunction', [123,'asd']);

......正确输出......

db = dbhandle
[123,"asd"]

...在动态添加的函数中使用常用的变量/句柄时删除丑陋的global要求?

通常情况下,我会按如下方式定义全局构造,但这可以理解为因致命错误Uncaught Error: Using $this when not in object context而失败...

class crunch {

    private $db;
    private $funcs = [];

    public function __construct($db) {
        $this->db = $db;
    }

    public function set($name, $function) {
        $this->funcs[$name] = $function;
    }

    public function call($function, $data=false) {
        if (isset($this->funcs[$function]) && is_callable($this->funcs[$function])) {
            return $this->funcs[$function]($data);
        }
    }
}

$db = 'dbhandle';

$crunch = new crunch($db);

$crunch->set('myfunction', function($data) {
    echo 'db = '. $this->db .'<br>'. json_encode( $data );
});

$crunch->call('myfunction', [123,'asd']);

实现目标的最简洁方法是什么?

编辑:正如@Rajdeep指出的那样,我可以在$crunch->set()函数中传递$ db。但我想避免这种情况,因为每个动态函数都可以引用这些私有变量的0-5,并且每个$crunch->set()调用所有5个函数是不优雅的。

1 个答案:

答案 0 :(得分:1)

您可以简单地将此变量传递给$db方法,而不是创建私有实例变量call()。你的代码应该是这样的:

class crunch {

    private $funcs = [];

    public function set($name, $function) {
        $this->funcs[$name] = $function;
    }

    public function call($function, $data=false, $db) {
        if (isset($this->funcs[$function]) && is_callable($this->funcs[$function])) {
            return $this->funcs[$function]($data, $db);
        }
    }
}

$db = 'dbhandle';

$crunch = new crunch();

$crunch->set('myfunction', function($data, $db){
    echo 'db = '. $db .'<br>'. json_encode( $data );
});

$crunch->call('myfunction', [123,'asd'], $db);

<强>输出:

db = dbhandle
[123,"asd"]

更新(1):

如果您只想将$db作为实例变量访问,解决方案将是这样的:

class crunch {

    public $db;
    private $funcs = [];

    public function __construct($db) {
        $this->db = $db;
    }

    public function set($name, $function) {
        $this->funcs[$name] = $function;
    }

    public function call($function, $data=false) {
        if (isset($this->funcs[$function]) && is_callable($this->funcs[$function])) {
            return $this->funcs[$function]($this, $data);
        }
    }
}

$db = 'dbhandle';

$crunch = new crunch($db);

$crunch->set('myfunction', function($crunch, $data) {
    echo 'db = '. $crunch->db .'<br>'. json_encode( $data );
});

$crunch->call('myfunction', [123,'asd']);

请注意您必须将$db作为公共成员变量,否则在调用set()方法时将无法访问。