类myClass { $myVariable = 'myCallback';
function myFunction() {
$body = false;
$callback = $this->myVariable;
function test($handle, $line) {
global $body, $callback;
if ($body) {
call_user_func($callback, $line);
}
if ($line === "\r\n") {
$body = true;
}
return strlen($line);
}
...
curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'test');
...
}
}
function myCallback($data) {
print $data;
}
$myCls = new myClass();
$myCls->myFunction();警告: call_user_func()函数。valid user-func:第一个参数应该是有效的回调!
我的$callback值为空,如何解决此问题?限制: myCallback函数不能更改!
发布于 2010-07-29 16:42:47
只是为了好玩,再来一个...(虽然没有经过测试)。
class myClass
{
protected $callback = 'myCallback';
protected $body = false;
public function myFunction()
{
...
curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, 'test'));
...
}
public function test($handle, $line)
{
if ($this->body) {
call_user_func($this->callback, $line);
}
if ($line === "\r\n") {
$body = true;
}
return strlen($line);
}
}
function myCallback($data) {
print $data;
}
$myCls = new myClass();
$myCls->myFunction();发布于 2010-07-29 15:58:59
重要提示:这只在>= 5.3中是可能的。OP不使用PHP5.3,但我将在这里留下答案,以防有人遇到类似的问题而使用PHP5.3。
$callback不是全局变量,它是方法范围内的局部变量。从documentation
闭包也可以从父作用域继承变量。任何这样的变量都必须在函数头中声明。从父作用域继承变量与使用全局变量不同。全局变量存在于全局作用域中,无论执行什么函数,全局作用域都是相同的。闭包的父作用域是声明闭包的函数(不一定是调用闭包的函数)。
使用use (并将函数赋给一个变量):
$test = function($handle, $line) use ($callback, $body){
if ($body) {
call_user_func($callback, $line);
}
if ($line === "\r\n") {
$body = true;
}
return strlen($line);
};之后的版本:
curl_setopt($ch, CURLOPT_WRITEFUNCTION, $test);发布于 2010-07-29 15:59:54
除了在声明$myVariable时缺少关键字之外,这根本不应该抛出错误,因为在test()函数中,$body为NULL,除非您在全局作用域中定义它。换句话说,你的myCallback永远不应该被调用。显然,您确实在全局范围内定义了$body,并使其成为为什么使用全局变量会导致各种意外行为的一个很好的例子。如果你想在全局作用域中定义$callback来保存'myCallback‘,它应该可以工作,但是你不需要全局变量。
帮你自己一个忙,去掉方法中的函数:
class myClass {
protected $_myVariable = 'myCallback';
public function myFunction()
{
// calling callback that calls callback (should make you think ;))
// that would be your curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'test');
echo call_user_func_array(
array($this, '_test'),
array('body', 'foo', 'bar'));
}
protected function _test($body, $handle, $line)
{
if ($body) {
call_user_func($this->_myVariable, $line);
}
if ($line === "\r\n") {
$body = true;
}
return strlen($line);
}
}test()函数现在是类中的一个方法。这比将代码流放到方法中的某个函数中要清晰得多,也更易于维护。注意,我传入了$body作为第一个参数。我不知道cURL是如何接受回调的,也不知道它传递给它们的是什么。如果您不能将$body作为第一个参数,请改为使用$this->body (as now shown by Philippe below)将其设置为类成员检查其状态
https://stackoverflow.com/questions/3360417
复制相似问题