保存来自PHP内部函数的数据


Saving a data from inner PHP function

我使用滚动cUrl PHP库从JSON API中获取数据。

在Rolling CURL库文档中,我尝试了以下示例,效果非常好:

$rollingCurl = new 'RollingCurl'RollingCurl();
$rollingCurl
    ->get('https://www.google.com')
    ->get('http://www.msn.com')
    ->setCallback(function('RollingCurl'Request $request, 'RollingCurl'RollingCurl $rollingCurl) {
        // parsing html with regex is evil (http://bit.ly/3x9sQX), but this is just a demo
        if (preg_match("#<title>(.*)</title>#i", $request->getResponseText(), $out)) {
            $title = $out[1];
        }
        else {
            $title = '[No Title Tag Found]';
        }
        echo "Fetch complete for (" . $request->getUrl() . ") $title " . PHP_EOL;
    })
    ->setSimultaneousLimit(3)
    ->execute();

和我试图改变它为我的需要,并保存数据为每个"刮"在一个数组中,但我找不到一种方法来保存数据从回调或它之外。

这是我尝试过的:

$rollingCurl = new 'RollingCurl'RollingCurl();
$rollingCurl
    ->get('https://www.myapi.com')
    ->get('https://www.myapi2.com')
    ->setCallback(function('RollingCurl'Request $request, 'RollingCurl'RollingCurl $rollingCurl) {
        $output = json_decode($request->getResponseText());
        $data[$x++] = $output; //How do I save it outside this function?
    })
    ->setSimultaneousLimit(3)
    ->execute();
//Can I get the content of each API call without the callback?
print_r($data); // returns nothing :(

所以我的问题是:

  1. 我如何保存数据数组这个函数之外?

  2. 我可以得到每个API调用的内容没有回调(执行后)?

我认为在回调闭包中初始化$datause应该可以解决您的问题。如果没有,你的$data数组只设置在闭包的范围内(声明回调函数时注意use (&$data)):

/** IMPORTANT **/
$data = array();
/***************/
$rollingCurl = new 'RollingCurl'RollingCurl();
$rollingCurl
    ->get('https://www.myapi.com')
    ->get('https://www.myapi2.com')
    ->setCallback(function('RollingCurl'Request $request, 'RollingCurl'RollingCurl $rollingCurl) use (&$data) {
        $output = json_decode($request->getResponseText());
        $data[$x++] = $output;
    })
    ->setSimultaneousLimit(3)
    ->execute();
// Yes, you can!
print_r($data);

我喜欢的另一个很好的特性是Closure作用域绑定,这只是一个快速且未经测试的例子(如果您需要更多的例子,请告诉我:)):

class CurlHandler {
    $data = array();
    public function processOutput($data) {
        // Do something with the data retrieved here
        $this->data[] = $data;
    }
    public function getData() { return $this->data; }
}
$curlResponseHandler = new CurlHandler();
// Your callback to be passed into 'RollingCurl'RollingCurl::setCallback()
$closure = function('RollingCurl'Request $request, 'RollingCurl'RollingCurl $rollingCurl) {
    $output = json_decode($request->getResponseText());
    $this->processOutput($output);
}
// Bind your callback Closure to your CurlHandler scope
// => the scope binding makes $this inside your callback Closure refer to your CurlHandler instance
$closure->bindTo($curlResponseHandler);
$rollingCurl = new 'RollingCurl'RollingCurl();
$rollingCurl
    ->get('https://www.myapi.com')
    ->get('https://www.myapi2.com')
    ->setCallback($closure)
    ->setSimultaneousLimit(3)
    ->execute();
// Get all your outputs from your CurlHandler class now:
print_r($curlResponseHandler->getData());

或者最后但并非最不重要的是直接在你的CurlHandler类上构造一个回调,这可能是我在这种情况下最喜欢的:

class CurlHandler {
    $data = array();
    public function processOutput('RollingCurl'Request $request, 'RollingCurl'RollingCurl $rollingCurl) {
        $output = json_decode($request->getResponseText());
        $this->data[] = $output;
    }
    public function getData() { return $this->data; }
}
$curlResponseHandler = new CurlHandler();
$rollingCurl = new 'RollingCurl'RollingCurl();
$rollingCurl
    ->get('https://www.myapi.com')
    ->get('https://www.myapi2.com')
    ->setCallback(array($curlResponseHandler, 'processOutput'))
    ->setSimultaneousLimit(3)
    ->execute();
// Get all your outputs from your CurlHandler class now:
print_r($curlResponseHandler->getData());

最后一个选项假设setCallback()一般接受可调用对象,而不仅仅是Closure

希望有帮助,干杯!