Скопируйте удаленный файл с помощью Guzzle

Я пытаюсь скопировать удаленный файл (изображение PNG, GIF, JPG …) на мой сервер. Я использую Guzzle, так как иногда получаю 404 с копией (), даже если файл существует, и мне также нужно сделать базовый auth. Этот скрипт находится в длинном скрипте, запущенном в команде, запущенной заданием cron. Я довольно новичок в Guzzle, и я успешно копирую изображение, но у моих файлов неправильный тип mime. Я должен делать что-то не так. Пожалуйста, предложите мне хороший способ сделать это (в том числе проверить успех / неудачу копирования и проверки типа mime). Если у файла нет типа mime, я бы вынул ошибку с подробной информацией.

Вот код:

$remoteFilePath = 'http://example.com/path/to/file.jpg'; $localFilePath = '/home/www/path/to/file.jpg'; try { $client = new Guzzle\Http\Client(); $response = $client->send($client->get($remoteFilePath)->setAuth('login', 'password')); if ($response->getBody()->isReadable()) { if ($response->getStatusCode()==200) { // is this the proper way to retrieve mime type? //$mime = array_shift(array_values($response->getHeaders()->get('Content-Type'))); file_put_contents ($localFilePath , $response->getBody()->getStream()); return true; } } } catch (Exception $e) { return $e->getMessage(); } 

Когда я делаю это, мой тип mime устанавливается в application / x-empty

Также похоже, что когда статус отличается от 200, Guzzle автоматически выдаст исключение. Как я могу остановить это поведение и проверить статус самостоятельно, чтобы я мог настраивать сообщение об ошибке?

EDIT: Это было для Guzzle 3.X Теперь вот как вы можете это сделать, используя Guzzle v 4.X (работает также с Guzzle 6)

 $client = new \GuzzleHttp\Client(); $client->get( 'http://path.to/remote.file', [ 'headers' => ['key'=>'value'], 'query' => ['param'=>'value'], 'auth' => ['username', 'password'], 'save_to' => '/path/to/local.file', ]); 

Или используя поток Gzzle:

 use GuzzleHttp\Stream; $original = Stream\create(fopen('https://path.to/remote.file', 'r')); $local = Stream\create(fopen('/path/to/local.file', 'w')); $local->write($original->getContents()); 

Это выглядит великолепно. Есть ли лучшее / правильное решение при использовании Guzzle 4?

Ваш код можно упростить. Мой примерный код ниже будет передавать тело ответа непосредственно в файловую систему.

 <?php function copyRemote($fromUrl, $toFile) { try { $client = new Guzzle\Http\Client(); $response = $client->get($fromUrl) ->setAuth('login', 'password') // in case your resource is under protection ->setResponseBody($toFile) ->send(); return true; } catch (Exception $e) { // Log the error or something return false; } } 

Когда я делаю это, мой тип mime устанавливается в application / x-empty

Миметик файловой системы?

Также похоже, что когда статус отличается от 200, Guzzle автоматически выдаст исключение. Как я могу остановить это поведение и проверить статус самостоятельно, чтобы я мог настраивать сообщение об ошибке?

Guzzle будет генерировать исключение для плохих ответов, таких как 4xx и 5xx. Не нужно отключать это. Просто поймайте исключение и обработайте ошибку там.

Посмотрите на это с сообщением:

  $myFile = fopen('path/to/file', 'w') or die('Problems'); $client = new \Guzzle\Service\Client(); $request = $client->post('https://www.yourdocumentpage.com', array(), ['pagePostField' => 'data'], ['save_to' => $myFile]); $client->send($request); fclose($myFile); 

здесь вы должны отправить запрос своего «сообщения»,

и с

  $myFile = fopen('path/to/file', 'w') or die('Problems'); $client = new \GuzzleHttp\Client(); $request = $client->get('https://www.yourdocumentpage.com', ['save_to' => $myFile]); 

и здесь вам не нужно отправлять запрос, и здесь вы найдете много документации, для этого вам понадобится gzzle 6, и если вы используете GOUTTE одновременно, вам понадобится goutte 3.1, обновите ваш запрос в вашем composer.json