Скопируйте удаленный файл с помощью Guzzle
Я пытаюсь скопировать удаленный файл (изображение PNG, GIF, JPG...) на мой сервер. Я использую Guzzle, так как иногда получаю 404 с copy(), даже если файл существует, и мне также нужно сделать базовый auth. Этот script находится в длинном script запущенном в команде, вызванном заданием 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?
Ответы
Ответ 1
Ваш код можно упростить. Мой примерный код ниже будет передавать тело ответа непосредственно в файловую систему.
<?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. Не нужно отключать это. Просто поймайте исключение и обработайте ошибку там.
Ответ 2
Посмотрите на это с сообщением:
$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);
здесь вы должны отправить запрос своего "сообщения"
и с get
$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