20

リモートファイル (画像 PNG、GIF、JPG ...) をサーバーにコピーしようとしています。ファイルが存在し、基本認証も行う必要がある場合でも、copy()で404 が発生することがあるため、Guzzleを使用します。このスクリプトは、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 は自動的に例外をスローするようです。エラーメッセージをカスタマイズできるように、この動作を停止して自分でステータスを確認するにはどうすればよいですか?

編集:これは 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 を使用する場合、より良い/適切な解決策はありますか?

4

3 に答える 3

22

コードを大幅に簡素化できます。以下のサンプル コードは、応答の本文をファイル システムに直接ストリーミングします。

<?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 などの不適切な応答に対して例外をスローします。これを無効にする必要はありません。例外をキャッチして、そこでエラーを処理するだけです。

于 2013-06-05T18:28:26.077 に答える
12

投稿でこれを見てください:

$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]);

ここではリクエストを送信する必要はありません。ここには多くのドキュメントがあります。それを行うには guzzle 6 が必要です。GOUTTE を同時に使用している場合は、goutte 3.1 が必要です。 composer.json で必要です

于 2015-08-28T20:23:48.437 に答える