Я пытаюсь скопировать удаленный файл (изображение 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