2015-10-17 3 views
1

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

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

ответ

1

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

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

Смежные вопросы