リモートファイル(画像PNG、GIF、JPGなど)をサーバーにコピーしようとしています。私は Guzzle を使用します。ファイルが存在し、基本的な認証を行う必要がある場合でも、 copy() で404が発生することがあります。このスクリプトは、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',
]);
またはGuzzleストリームを使用:
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に設定されます
ファイルシステムのMIMEタイプ?
また、ステータスが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);
ここにあなたの「投稿」のリクエストを送信する必要があります
そしてgetで
$myFile = fopen('path/to/file', 'w') or die('Problems');
$client = new \GuzzleHttp\Client();
$request = $client->get('https://www.yourdocumentpage.com', ['save_to' => $myFile]);
そしてここではリクエストを送信する必要はありません、そして here たくさんのドキュメントを見つけるでしょう、それを行うにはguzzle 6が必要です、そして同時にGOUTTEを使用しているなら'goutte 3.1が必要です。composer.jsonでrequireを更新してください
guzzle 6を使用する場合は、SINKオプションを使用するだけです。以下の詳細な機能を参照してください
追加:
guzzleHttp\Clientを使用します。含まれるGuzzle名前空間
$ access_token =認証が必要な場合は、このオプションを削除してください
ReportFileDownloadException =カスタム例外
/**
* download report file and read data to database
* @param remote url
* @return N/A
* @throws ReportFileDownloadException
*/
protected function getReportFile($report_file_url)
{
$file = $this->tempDirectory . "/" . basename($report_file_url);
$fileHandle = fopen($file, "w+");
try {
$client = new Client();
$response = $client->get($report_file_url, [
RequestOptions::SINK => $fileHandle,
RequestOptions::HEADERS => [
"Authorization" => "Bearer $access_token"
]
]);
} catch (RequestException $e) {
throw new ReportFileDownloadException(
"Can't download report file $report_file_url"
);
} finally {
@fclose($fileHandle);
}
throw new ReportFileDownloadException(
"Can't download report file $report_file_url"
);
}