Сохранение данных из внутренней функции PHP

1

Я использую библиотеку Rolling cUrl PHP для получения данных из API с помощью JSON.

В документации библиотеки 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 без обратного вызова (после выполнения)?

Теги:
curl

1 ответ

1

Я думаю, что инициализация $data и use его внутри callback Closure должно решить вашу проблему. Без этого ваш массив $data будет установлен только в области вашего Closure (обратите внимание на 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 s.

Надеюсь, что это поможет, ура!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню