Сделать вывод CURL STDERR в файл (или строку)
Мы пытаемся отладить некоторые ошибки cURL на сервере, и мне бы хотелось увидеть журнал STDERR. В настоящее время мы видим, что наша ошибка - "код ошибки: 7", и мы не можем подключиться к целевому серверу. Мы связались с хостом и сделали специальное правило, чтобы открыть необходимый нам порт, и мы пока игнорируем сертификат.
Тем не менее, мы не можем подключиться. Мне нужно отладить это, но я не вижу никакой соответствующей информации на моем конце.
Линии, упоминающие "VERBOSE" и "STDERR", являются самыми важными, я думаю. Ничего не написано в $curl_log. Что я делаю не так? Следуя логике руководств, это должно быть правильно...
Используемый PHP:
<?php
$curl = curl_init();
$curl_log = fopen("curl.txt", 'w');
$url = "http://www.google.com";
curl_setopt_array($curl, array(
CURLOPT_URL => $url, // Our destination URL
CURLOPT_VERBOSE => 1, // Logs verbose output to STDERR
CURLOPT_STDERR => $curl_log, // Output STDERR log to file
CURLOPT_SSL_VERIFYPEER => 0, // Do not verify certificate
CURLOPT_FAILONERROR => 0, // true to fail silently for http requests > 400
CURLOPT_RETURNTRANSFER => 1 // Return data received from server
));
$output = fread($curl_log, 2048);
echo $output; // This returns nothing!
fclose($curl_log);
$response = curl_exec($curl);
//...restofscript...
?>
Из руководства PHP: http://php.net/manual/en/function.curl-setopt.php
CURLOPT_VERBOSE ИСТИНА для вывода подробной информации. Записывает вывод в STDERR CURLOPT_STDERR Альтернативное местоположение для вывода ошибок вместо STDERR.
Это тоже не проблема разрешения. Я установил файл и script разрешения на 777 на стороне сервера, а мой локальный клиент - это окна и никогда не заботился о настройках разрешений (это только для dev в любом случае).
Ответы
Ответ 1
Вы делаете ошибки в вашем примере:
1) вам нужно позвонить curl_exec()
перед чтением из "подробного журнала", потому что curl_setopt()
не выполняет никаких действий, поэтому до curl_exec ничего не может быть зарегистрировано ().
2) вы открываете $curl_log = fopen("curl.txt", 'w');
только для записи, поэтому ничто не может быть прочитано даже после того, как вы напишете файл и перемотаете внутренний указатель файла.
Итак, правильный сокращенный код должен выглядеть так:
<?php
$curl = curl_init();
$curl_log = fopen("curl.txt", 'rw'); // open file for READ and write
$url = "http://www.google.com";
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_VERBOSE => 1,
CURLOPT_STDERR => $curl_log,
CURLOPT_RETURNTRANSFER => 1
));
$response = curl_exec($curl);
rewind($curl_log);
$output= fread($curl_log, 2048);
echo "<pre>". print_r($output, 1). "</pre>";
fclose($curl_log);
// ...
?>
ПРИМЕЧАНИЕ: подробный журнал может быть длиннее 2048 байт, поэтому вы можете "fclose" $curl_log после curl_exec(), а затем прочитать весь файл, например file_get_contents().
В этом случае точка 2) не должна рассматриваться как ошибка: -)
Ответ 2
Немного поздно для вечеринки, но эта страница по-прежнему всплывает в Google, поэтому отпустите.
Кажется, что CURLOPT_VERBOSE ничего не записывает, если для CURLINFO_HEADER_OUT также установлено значение TRUE.
Это ошибка в PHP (# 65348), и по причинам, которые они решили не исправлять.
Ответ 3
Объединяя al выше ответы, я использую эту функцию, чтобы сделать запрос на зависание с параметром loggin для файла:
function CURLPostRequest($url, array $post = NULL, array $options = array(), $log_file = NULL){
$defaults = array(
CURLOPT_POST => 1,
CURLOPT_HEADER => 0,
CURLOPT_URL => $url,
CURLOPT_FRESH_CONNECT => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FORBID_REUSE => 1,
CURLOPT_TIMEOUT => 4,
CURLOPT_POSTFIELDS => http_build_query($post)
);
if (is_resource($log_file)){
$defaults[CURLOPT_VERBOSE]=1;
$defaults[CURLOPT_STDERR]=$log_file;
$defaults[CURLINFO_HEADER_OUT]=1;
}
$ch = curl_init();
curl_setopt_array($ch, ($options + $defaults));
if( ! $result = curl_exec($ch)){
throw new Exception(curl_error($ch));
}
if (is_resource($log_file)){
$info = curl_getinfo($ch);
if (isset($info['request_header'])){
fwrite($log_file, PHP_EOL.PHP_EOL.'* POST Content'.PHP_EOL.PHP_EOL);
fwrite($log_file, print_r($info['request_header'],true));
fwrite($log_file, http_build_query($post));
}
fwrite($log_file, PHP_EOL.PHP_EOL.'* Response Content'.PHP_EOL.PHP_EOL);
fwrite($log_file, $result.PHP_EOL.PHP_EOL);
}
curl_close($ch);
return $result;
}
Надеюсь, что это поможет кому-то.
Ответ 4
Из справочника php для функции curl_setopt:
CURLOPT_FILE The file that the transfer should be written to. The default is STDOUT (the browser window).
Ответ 5
Вы должны положить
$output = fread($curl_log, 2048);
echo $output; // This returns nothing!
fclose($curl_log);
после $response = curl_exec($curl);
в противном случае файл закрывается во время выполнения curl.