【问题标题】:Saving a data from inner PHP function从内部 PHP 函数保存数据
【发布时间】:2016-01-16 02:59:36
【问题描述】:

我正在使用Rolling 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调用的内容吗?

【问题讨论】:

    标签: php curl


    【解决方案1】:

    我认为在回调闭包中初始化 $datause 应该可以解决您的问题。否则,您的 $data 数组仅设置在您的闭包范围内(在声明回调函数时请注意 use (&amp;$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() 通常接受可调用对象,而不仅仅是Closures。

    希望对您有所帮助,干杯!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-05
      • 2014-04-14
      • 1970-01-01
      相关资源
      最近更新 更多