Я уже некоторое время изучаю и экспериментирую с этой проблемой и еще не нашел работоспособного решения, поэтому я думаю, что пришло время обратиться за помощью.
У меня проблема с curl_exec, но только на определенном сервере. Вот некоторые предпосылки:
PHP-код, который показывает проблему:
$input_vars = (!empty($_POST)) ? filter_input_array(INPUT_POST) : array(); $url = 'http://192.168.1.100/geekcavecreations/Morti/chatbot/conversation_start.php'; $qs = '?'; foreach ($input_vars as $key => $value) { $qs .= "$key=$value&"; } $qs= rtrim($qs, '&'); $url .= $qs; $bot_id = $input_vars['bot_id']; $options = array( CURLOPT_USERAGENT => 'Program O XML API', CURLOPT_RETURNTRANSFER => true, //CURLOPT_POST => 1, CURLOPT_MAXREDIRS => 5, CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => 5, ); $ch = curl_init($url); curl_setopt_array($ch, $options); //curl_setopt($ch, CURLOPT_POSTFIELDS, $input_vars); $data = curl_exec($ch); $debug = curl_getinfo($ch); curl_close($ch); echo '<pre>Data = ', htmlentities($data), '</pre><br>'; var_dump($debug);
Как видно, я пробовал это как с GET, так и с POST, и оба дают одинаковые результаты. Параметры тайм-аута, перечисленные выше, существуют, чтобы сценарий не запускался неопределенно. У меня было это зависание более 3 часов, прежде чем я остановлю службу Apache, чтобы остановить зависание (просто отмена в браузере этого не сделает). Результат скрипта выглядит следующим образом:
array (size=26) 'url' => string 'ht tp://192.168.1.100/geekcavecreations/Morti/chatbot/conversation_start.php?say=hello&bot_id=1&convo_id=78a9s39gut34lurq055in5s6r4&format=xml' (length=141) 'content_type' => null 'http_code' => int 0 'header_size' => int 0 'request_size' => int 203 'filetime' => int -1 'ssl_verify_result' => int 0 'redirect_count' => int 0 'total_time' => float 5 'namelookup_time' => float 0 'connect_time' => float 0 'pretransfer_time' => float 0 'size_upload' => float 0 'size_download' => float 0 'speed_download' => float 0 'speed_upload' => float 0 'download_content_length' => float -1 'upload_content_length' => float 0 'starttransfer_time' => float 0 'redirect_time' => float 0 'redirect_url' => string '' (length=0) 'primary_ip' => string '192.168.1.100' (length=13) 'certinfo' => array (size=0) empty 'primary_port' => int 80 'local_ip' => string '192.168.1.100' (length=13) 'local_port' => int 2546 Data =
(не могу понять, лучший способ форматирования, извините)
Также на этом же компьютере находятся несколько виртуальных машин, каждый из которых имеет разные версии ОС / Server / PHP, и все они имеют точно такой же корень физического документа, который находится на главной машине. Эти машины варьируются от Windows 7 / IIS до CentOS / Apache 2.2 и других комбинаций, и все они без исключения запускают этот же скрипт без проблем и выводят ожидаемый XML-документ. Если я запускаю URL-адрес только в веб-браузере, вывод выглядит следующим образом:
<?xml version="1.0"?> <program_o> <version>2.3.0</version> <status><success>1</success></status> <bot_id>1</bot_id> <bot_name>Morti</bot_name> <user_id>1</user_id> <user_name>Seeker</user_name> <chat> <line> <input>hello</input> <response>And a good failed to you, undefined. How are you?</response> </line> </chat> </program_o>
Я также взял вышеупомянутый вывод XML и сохранил его в файле, и скрипт проблемы выполнял вызов cURL по URL-адресу для этого сохраненного XML-файла, и скрипт работает без проблем в этот момент, поэтому я также создал mock-up script, который создает только объект SimpleXMLElement, заполняет несколько новых тегов, а затем echo выводит asXML () из созданного объекта (в основном, что делает chat_start.php, но гораздо менее сложным), и я получаю ту же проблему. Код для макета-сценария ниже:
$xml = new SimpleXMLElement('<program_o></program_o>'); $xml->addChild('version', '2.3.0'); $status = $xml->addChild('status'); $status->addChild('success', '1'); $xml->addChild('bot_id', '1'); $xml->addChild('bot_name', 'Morti'); $xml->addChild('user_id', '1'); $xml->addChild('user_name', 'Seeker'); $chat = $xml->addChild('chat'); $line = $chat->addChild('line'); $line->addChild('input', 'hello'); $line->addChild('response', 'And a good failed to you, undefined. How are you?'); $output = $xml->asXML(); header('Content-type: text/xml'); exit($output);
Я в значительной степени нахожусь здесь. Я изменил версии PHP, версии Apache, попробовал бесчисленные предложения, которые я нашел здесь в SO для других проблем с замораживанием cURL, как здесь , здесь и здесь , среди двух десятков или более других.
И теперь, когда я написал книгу, чтобы представить свою проблему, я должен спросить: как я могу заставить cURL удержаться от зависания на платформе Windows 8?
Ну, похоже, я, наконец, добрался до корня проблемы. Кажется, что когда вы выполняете вызов cURL на тот же сервер, что и скрипт, выполняющий вызов, и если оба сценария «вызывающий» и «вызываемый» пытаются использовать один и тот же идентификатор сеанса, возникает взаимоблокировка, вызывающая как скрипты, ожидающие окончания сеанса. Я закончил тем, что добавил тест, чтобы увидеть, есть ли уже используемый идентификатор сеанса, и если это так, вызывающий скрипт не запускает сеанс. Если идентификатор сеанса отсутствует, то вызывающий абонент запускает сеанс, получает идентификатор сеанса, а затем уничтожает сеанс, который позволяет сценарию «вызываемого» неограниченного доступа к указанному сеансу, тем самым устраняя ситуацию взаимоблокировки. Ниже приведен код, который я использовал для этого:
$convo_id = (isset ($request_vars['convo_id'])) ? $request_vars['convo_id'] : get_convo_id(); // do stuff here function get_convo_id() { session_name('Program O XML GUI'); session_start(); $convo_id = session_id(); session_destroy(); return $convo_id; }
Используя этот метод, все работает так, как ожидалось. Я искренне надеюсь, что это окажется полезным для других в будущем.