首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP / Scope / Callback

PHP / Scope / Callback
EN

Stack Overflow用户
提问于 2010-07-29 15:54:19
回答 3查看 1.2K关注 0票数 4

类myClass { $myVariable = 'myCallback';

代码语言:javascript
复制
    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函数不能更改!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-07-29 16:42:47

只是为了好玩,再来一个...(虽然没有经过测试)。

代码语言:javascript
复制
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();
票数 2
EN

Stack Overflow用户

发布于 2010-07-29 15:58:59

重要提示:这只在>= 5.3中是可能的。OP不使用PHP5.3,但我将在这里留下答案,以防有人遇到类似的问题而使用PHP5.3。

$callback不是全局变量,它是方法范围内的局部变量。从documentation

闭包也可以从父作用域继承变量。任何这样的变量都必须在函数头中声明。从父作用域继承变量与使用全局变量不同。全局变量存在于全局作用域中,无论执行什么函数,全局作用域都是相同的。闭包的父作用域是声明闭包的函数(不一定是调用闭包的函数)。

使用use (并将函数赋给一个变量):

代码语言:javascript
复制
$test = function($handle, $line) use ($callback, $body){

    if ($body) {
        call_user_func($callback, $line);
    }

    if ($line === "\r\n") {
        $body = true;
    }

    return strlen($line);
};

之后的版本:

代码语言:javascript
复制
curl_setopt($ch, CURLOPT_WRITEFUNCTION, $test);
票数 10
EN

Stack Overflow用户

发布于 2010-07-29 15:59:54

除了在声明$myVariable时缺少关键字之外,这根本不应该抛出错误,因为在test()函数中,$bodyNULL,除非您在全局作用域中定义它。换句话说,你的myCallback永远不应该被调用。显然,您确实在全局范围内定义了$body,并使其成为为什么使用全局变量会导致各种意外行为的一个很好的例子。如果你想在全局作用域中定义$callback来保存'myCallback‘,它应该可以工作,但是你不需要全局变量。

帮你自己一个忙,去掉方法中的函数:

代码语言:javascript
复制
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)将其设置为类成员检查其状态

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3360417

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档