2012-03-23 2 views
5

Итак, я использовал ampps, а затем переключился на z-wamp, думая, что это решит проблему, но это не так.php single curl works но multi curl не работает?

У меня есть отдельные «сайты» в моем локальном хосте (localhost/site1 & localhost/site2), на которые я пытаюсь отправить несколько запросов на завивки, но по какой-то нечетной причине это ничего не делает! Он работает только тогда, когда я делаю один завиток на одном сайте. Это работает:

$ch = curl_init('http://localhost/site1/'); 
curl_setopt_array($ch, array(
    CURLOPT_RETURNTRANSFER => true, 
    CURLOPT_HEADER => false, 
    CURLOPT_POST => true, 
    CURLOPT_POSTFIELDS => array('data' => $data) 
)); 
$res = curl_exec($ch); 
//yay! 

В другой стороны, это не работает:

... 
//add a bunch of curl sessions 
//to $this->sessions 
... 
$window = 15; 
if (count($this->sessions) < $window) 
    $window = count($this->sessions); 

$mh = curl_multi_init(); 

$site_map = array(); 

for ($i = 0; $i < $window; ++$i) { 
    curl_multi_add_handle($mh, $this->sessions[$i]); 
    $site_map[(string) $this->sessions[$i]] = $i; 
} 

$data_results = array(); 
$running = null; 

do { 
    $execrun = curl_multi_exec($mh, $running); 
} while ($execrun === CURLM_CALL_MULTI_PERFORM); 

while ($running && $execrun === CURLM_OK) { 

    //the loop just keeps going forever from here 

    if (curl_multi_select($mh) !== -1) { 
     do { 
      $execrun = curl_multi_exec($mh, $running); 
     } while ($execrun === CURLM_CALL_MULTI_PERFORM); 
    } 

    if ($execrun !== CURLM_OK) 
     break; 

    //to here and never enters the loop below 

    while ($done = curl_multi_info_read($mh)) { 

     $output = curl_multi_getcontent($done['handle']); 

     if ($output) 
      $data_results[$site_map[(string) $done['handle']]] = $output; 
     else 
      $data_results[$site_map[(string) $done['handle']]] = null; 

     if (isset($this->sessions[$i]) && $i < count($this->sessions)) { 
      curl_multi_add_handle($mh, $this->sessions[$i]); 
      $site_map[(string) $this->sessions[$i]] = $i; 
      ++$i; 
     } 

     unset($site_map[(string) $done['handle']]); 
     curl_multi_remove_handle($mh, $done['handle']); 
     curl_close($done['handle']); 
    } 
} 
curl_multi_close($mh); 
return $data_results; 

Так в несколько коде завитка выше, он начинает идти, добавляет ручку к $ мГн, и один раз он выполняет, он будет продолжать цикл и никогда не войдет в цикл $ done = curl_multi_info_read ($ mh) while. Тем временем он все еще работает нормально, а также $ running равно 2 все время. Кроме того, curl_multi_info_read вернет false. Так что он просто зацикливается навсегда.

Моего локон расширение включено (очевидно, если одиночные локоны работа) и здесь детали из него PHP Info:

cURL support enabled 
cURL Information 7.24.0 
Age 3 
Features 
AsynchDNS Yes 
Debug No 
GSS-Negotiate No 
IDN No 
IPv6 Yes 
Largefile Yes 
NTLM Yes 
SPNEGO No 
SSL Yes 
SSPI No 
krb4 No 
libz Yes 
CharConv No 
Protocols dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, pop3, pop3s, rtsp, scp, sftp, smtp, smtps, telnet, tftp 
Host i386-pc-win32 
SSL Version OpenSSL/1.0.0g 
ZLib Version 1.2.5 
libSSH Version libssh2/1.3.0 

Что в мире происходит с этой штукой? Может быть, это что-то с моей конфигурацией PHP? Конфигурация Apache? Еще раз, я использую z-wamp.

PHP версии 5.3.10 Apache версии 2.4.1 Win 7 64-бит Добавлен PHP каталог в PATH

Редактировать Оказывается, что он должен быть какой-то Apache/PHP конфигурации типа, который я вообще не могу заметить, потому что я покончил с z-wamp и установил wampserver, и он работал на этот раз.

+0

Оператор 'break' выходит из основного цикла while. Это предназначено? – Brad

+0

Этот оператор break не связан с проблемой, потому что он никогда не запускается. Я не поместил его туда, он пришел с библиотекой, в которую я адаптировал свой код. – rclai

+0

Вы, кажется, слишком быстро удаляете ручки. – PFY

ответ

4

Я только что ответил на другой вопрос, который я нашел о нескольких вызовах с завихрением.

Это все, что я сделал для выполнения запросов.

do { 
    $status = curl_multi_exec($mh, $running); 
} while ($status === CURLM_CALL_MULTI_PERFORM || $running); 

Затем я получил информацию, необходимую мне, перейдя через мой массив обработчиков завитушек.

$returned = array(); 
foreach ($requests as $identifier => $request) { 
    $returned[$identifier] = curl_multi_getcontent($request); 
    curl_multi_remove_handle($mh, $request); 
    curl_close($request); 
} 

выше подход работал для меня, однако, кажется, что вы хотите добавить только определенное количество сеансов завитка мульти-обработчика. Мы могли бы изменить цикл Do-While выше следующее:

do { 
    $status = curl_multi_exec($mh, $running); 
    if ($running < $window) { 
     for ($x = 0; $x < $window - $running; $x++) { 
      $index = count($site_map) + $x -1; 
      curl_multi_add_handle($mh, $this->sessions[$index]); 
      $site_map[(string) $this->sessions[$index]] = $index; 
     } 
    } 
} while ($status === CURLM_CALL_MULTI_PERFORM || $running); 

После того, что мы могли бы изменить выборку данных и заменить всю while ($running && $execrun === CURLM_OK){} раздела со следующим, так как он будет работать только один раз все ваши локонов звонки были обрабатываются:

$returned = array(); 
foreach ($this->sessions as $identifier => $request) { 
    $returned[$identifier] = curl_multi_getcontent($request); 
    curl_multi_remove_handle($mh, $request); 
    curl_close($request); 
} 
+0

Спасибо за этот код. Это похоже на более холодный способ дросселирования завихрений. – rclai

+0

@ rclai89 Я немного изменил положение дел. Я ошибочно полагался на счет '$ this-> session', но должен был рассчитывать' $ site_map' (как вы делаете дальше). Надеюсь, это сработает для вас :) – Crashspeeder

0

Я попытался запустить как опалить curl_exec() и curl_multi_exec() на той же странице, но не получил никакого ответа, а также, пока я не сделал: unset($ch);, после того, как один запрос.