it-swarm.com.de

Kopieren Sie die entfernte Datei mit Guzzle

Ich versuche, eine entfernte Datei (Bild PNG, GIF, JPG ...) auf meinen Server zu kopieren. Ich benutze Guzzle , da ich manchmal 404 mit copy () bekomme, auch wenn die Datei existiert und ich auch ein grundlegendes Auth tun muss. Dieses Skript befindet sich in einem langen Skript, das in einem Befehl gestartet wird, der durch einen Cron-Job ausgelöst wird .. Ich bin ziemlich neu bei Guzzle und kopiere das Bild erfolgreich, aber meine Dateien haben den falschen MIME-Typ. Ich muss hier etwas falsch machen. Bitte schlagen Sie mir eine gute Möglichkeit vor, dies zu tun (einschließlich Überprüfung des Erfolgs/Fehlschlags der Kopie und Überprüfung des MIME-Typs). Wenn die Datei keinen MIME-Typ hat, würde ich einen Fehler mit Detailinformationen anzeigen.

Hier ist der Code:

$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();
}

Wenn ich dies tue, ist mein Mime-Typ auf application/x-empty gesetzt. 

Es sieht auch so aus, als würde der Status von 200 abweichen. Guzzle wird automatisch eine Ausnahme auslösen. Wie kann ich dieses Verhalten beenden und den Status selbst überprüfen, damit ich eine benutzerdefinierte Fehlermeldung erhalten kann?

EDIT: Dies war für Guzzle 3.X Jetzt können Sie es mit Guzzle v 4.X (funktioniert auch mit 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',
    ]);

Oder mit Guzzle-Stream:

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());

Das sieht gut aus. Gibt es eine bessere/richtige Lösung bei der Verwendung von Guzzle 4?

17
Spir

Ihr Code kann sehr vereinfacht werden. Mein Beispielcode unten wird den Hauptteil der Antwort direkt an das Dateisystem streamen.

<?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;
    }
}

Wenn ich dies tue, ist mein Mime-Typ auf application/x-empty gesetzt

Ein Dateisystem-Mimetyp?

Es sieht auch so aus, als würde der Status von 200 abweichen. Guzzle wird automatisch eine Ausnahme auslösen. Wie kann ich dieses Verhalten beenden und den Status selbst überprüfen, damit ich eine benutzerdefinierte Fehlermeldung erhalten kann?

Guzzle löst bei schlechten Antworten wie 4xx und 5xx eine Ausnahme aus. Keine Notwendigkeit, dies zu deaktivieren. Fangen Sie einfach eine Ausnahme und behandeln Sie den Fehler dort.

21
Michael Dowling

Schau dir das mit dem Post an:

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

hier müssen Sie die Anfrage Ihres "Beitrags" senden

und mit bekommen

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

und hier brauchen Sie nicht die Anfrage zu senden, und hier Sie finden eine Menge Dokumentation, Sie müssen 6 dafür haben und wenn Sie gleichzeitig GOUTTE verwenden brauche goutte 3.1, aktualisiere deinen Bedarf in deiner composer.json

10
Jorgeeadan

mit Guzzle 6 verwenden Sie einfach die SINK-Option. siehe unten ausführliche Funktion 

Extra:

verwenden Sie GuzzleHttp\Client. Guzzle-Namensraum enthalten

$ access_token = Wenn Sie Auth brauchen, entfernen Sie einfach diese Option

ReportFileDownloadException = benutzerdefinierte Ausnahme

/**
 * 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"
    );
}
2
Furqan Freed