PHP curl: проверить ответ на ошибку перед сохранением в файл

У меня есть скрипт curl, который при успешном выполнении возвращает двоичный контент, который мне нужно сохранить в файл (file.wav).

Но, в случае ошибки, он возвращает ошибку в формате json, как

'{ "code" : 401 , "error" : "Not Authorized" , "description" : "..." } '

мой скрипт

    $text_data = [
        'text' => $this->text
    ];
    $text_json = json_encode($text_data);

    $output_file = fopen($this->output_file_path, 'w');

    # url
    $url = $this->URL.'?voice='.$this->voice;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_USERPWD, $this->USERNAME.':'.$this->PASSWORD);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Accept: audio/'.$this->audio_format,
    ]);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $text_json);
    curl_setopt($ch, CURLOPT_FILE, $output_file);
    curl_setopt($ch, CURLOPT_HEADER, true);

    $result = curl_exec($ch);
    if (curl_errno($ch)) {
        throw new Exception('Error with curl response: '.curl_error($ch));
    }
    curl_close($ch);
    fclose($output_file);

    $decode_result = json_decode($result);

    if (key_exists('error', $decode_result)) {
        throw new Exception($decode_result->description, $decode_result->code);
    }

    if ($result && is_file($this->output_file_path))
        return $this->output_file_path;

    throw new Exception('Error creating file');

Это прекрасно работает, когда результат успешен. Но когда есть ошибка, сообщение об ошибке также сохраняется в output_file и, таким образом, этот файл не читается.

Как я могу проверить наличие ошибок перед сохранением в файл?

Изменить 2: проверить заголовки ответа

    $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
    $header = substr($result, 0, $header_size);
    $body = substr($result, $header_size);

    debug($header_size);      // always prints `false`
    debug($header);           // ''
    debug($body);             // '1'

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

1 ответ

Решение

Сделайте curl_getinfo() перед записью в файл (и не открывайте его в начале кода).

Пример:

$ch = curl_init('http://www.google.com/');
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$c = curl_exec($ch);

if(curl_getinfo($ch, CURLINFO_HTTP_CODE) != 200)
    echo "Something went wrong!";

Любой код ответа не 200 (успех) считается ошибкой, приведенный выше код, скорее всего, не вернет ничего, так как google.com запущен и работает в сети;)

Другие вопросы по тегам