2013-06-05 5 views
16

Ich versuche, eine Remote-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 eine grundlegende Auth tun muss. Dieses Skript befindet sich in einem langen Skript, das in einem durch einen Cron-Job ausgelösten Befehl gestartet wird. Ich bin ziemlich neu zu Guzzle und ich kopiere erfolgreich das Bild, aber meine Dateien haben falschen Mime-Typ. Ich muss hier etwas falsch machen. Bitte schlagen Sie mir einen guten Weg vor, dies zu tun (einschließlich Überprüfung des Erfolgs/Misserfolgs der Kopier- und Mime-Typ-Prüfung). Wenn die Datei keinen MIME-Typ hat, würde ich einen Fehler mit Detailinformationen ausgeben. HierKopiere Remote-Datei mit Guzzle

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 tun, mein MIME-Typ festgelegt ist application/x-leer

Auch sieht es so aus, wenn der Status unterscheidet sich von 200 Guzzle automatisch eine Ausnahme auslösen Wie kann ich dieses Verhalten stoppen und Status selbst überprüfen, damit ich benutzerdefinierte Fehlermeldung kann?

EDIT: Das war für Guzzle 3.X Nun ist dies, wie Sie es tun können Guzzle v 4.X mit (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?

Antwort

21

Ihr Code kann sehr vereinfacht werden. Mein Beispielcode streamt den Body der Antwort direkt zum Dateisystem.

<?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 tun, mein MIME-Typ application/x-leer

Ein Dateisystem MIME-Typ festgelegt ist?

Auch sieht es so aus, wenn sich der Status von 200 unterscheidet Guzzle wird automatisch eine Ausnahme auslösen. Wie kann ich dieses Verhalten stoppen und Status selbst überprüfen, damit ich benutzerdefinierte Fehlermeldung kann?

Guzzle wird eine Ausnahme für schlechte Antworten wie 4xx und 5xx werfen. Keine Notwendigkeit, dies zu deaktivieren. Fange einfach eine Ausnahme und behandle den Fehler dort.

+0

Vielen Dank!Ich werde es versuchen. Ich hoffe, dass es propre mime Typ (Original Mime Typ) hält. – Spir

+0

Sie müssen etwas an Ihrem Ende tun, um eine Datei auf dem Datenträger zu aktualisieren, um eine Art MIME-Type zu verwenden. Davon habe ich aber noch nie gehört. –

+0

Nein, ich meinte die Art, wie ich es gemacht habe, brach/verlor den Pantomime Typ. Ihre Lösung funktioniert gut. Danke für die Hilfe. – Spir

10

Schauen Sie sich diese mit der Post:

$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 den Wunsch Ihres "post" 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 zu senden Sie die Anfrage, und here Sie werden eine Menge Dokumentation finden, müssen Sie guzzle 6 dafür haben, und wenn Sie GOUTTE zur gleichen Zeit verwenden, brauchen Sie goutte 3.1, update Ihre Anforderung in Ihrem composer.json

+0

ist es besser? –

+1

Dies funktionierte mit Guzzle 5.3.x, mit der Option 'save_to' wurde die Aufgabe erledigt. Vielen Dank! –

+4

Nur eine Anmerkung - in Guzzle 6, "die save_to Anfrage Option wurde veraltet zugunsten der Sink-Anfrage-Option. Bereitstellung der save_to Option ist jetzt ein Alias ​​von Senke". – TeeJay