Заставьте 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 TRUE для вывода подробной информации. Записывает вывод в STDERR CURLOPT_STDERR Альтернативное место для вывода ошибок вместо STDERR.

Это также не проблема с разрешениями, я установил права доступа к файлам и сценариям на 777 на стороне сервера, а мой локальный клиент - это Windows, и он никогда не заботился о настройках разрешений (в любом случае, это только для разработчиков).


person Radley Sustaire    schedule 15.01.2012    source источник
comment
Скрипт завершен? Я спрашиваю, потому что отсутствует curl_exec(). И какой результат вы ожидаете (и почему)?   -  person Progman    schedule 15.01.2012
comment
О, да, я удалил это в своем копипасте. Верните curl_exec. Я надеюсь получить какую-то отладочную информацию, хотя на самом деле я понятия не имею, чего от нее ожидать. Я понятия не имею, что вызывает сбой соединения на стороне сервера.   -  person Radley Sustaire    schedule 15.01.2012
comment
это помогло мне найти, где реальная проблема описание здесь   -  person Darkcoder    schedule 18.06.2020


Ответы (6)


Вы делаете пару ошибок в своем примере:

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) не следует считать ошибкой :-)

person Jonez1    schedule 30.12.2012

Немного опоздал на вечеринку, но эта страница все еще всплывает высоко в Google, так что поехали.

Кажется, что CURLOPT_VERBOSE ничего не регистрирует, если для CURLINFO_HEADER_OUT также установлено значение TRUE.

Это известная ошибка в PHP (#65348), и по причинам, решил не исправлять.

person DavidKunz    schedule 06.09.2016

Собрав все вышеперечисленные ответы вместе, я использую эту функцию, чтобы сделать запрос Curl Post с параметром входа в файл:

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;
}

Надеюсь, это поможет кому-то.

person ontananza    schedule 18.11.2014
comment
должно быть $defaults[CURLINFO_HEADER_OUT]=1; подробное не записывается, когда CURLINFO_HEADER_OUT включен - person Brad Kent; 04.03.2018

Из руководства по php для функции curl_setopt:

CURLOPT_FILE The file that the transfer should be written to. The default is STDOUT (the browser window).  
person rkosegi    schedule 15.01.2012
comment
CURLOPT_VERBOSE утверждает, что пишет в STDERR, когда CURLOPT_FILE выводит данные? CURLOPT_FILE => $curl_log ...по-прежнему не пишет в файл. - person Radley Sustaire; 15.01.2012

Вы должны положить

$output = fread($curl_log, 2048);
echo $output; // This returns nothing!
fclose($curl_log);

после $response = curl_exec($curl); в противном случае файл закрывается во время выполнения curl.

person Mine    schedule 28.12.2012

Мне нужно было закрыть файл, прежде чем я смог его прочитать, это сработало для меня:

$filename = 'curl.txt';
$curl_log = fopen($filename, 'w'); // open file for write (rw, a, etc didn't help)
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_STDERR, $curl_log);        

$result = curl_exec($ch);

fclose($curl_log);      
$curl_log = fopen($filename, 'r'); // open file for read
$output= fread($curl_log, filesize($filename));
echo $output;

(PHP 5.6.0, Apache/2.2.15)

person Aba    schedule 18.03.2019