example - httpclient php
Copie el archivo remoto usando Guzzle (3)
Estoy intentando copiar un archivo remoto (imagen PNG, GIF, JPG ...) a mi servidor. Utilizo Guzzle porque a veces obtengo 404 con copy() incluso si el archivo existe y también necesito hacer una autenticación básica. Esta secuencia de comandos se encuentra dentro de una secuencia de comandos larga iniciada en un comando activado por un trabajo cron. Soy bastante nuevo en Guzzle y copié la imagen con éxito, pero mis archivos tienen un tipo de mimo incorrecto. Debo estar haciendo algo mal aquí. Por favor, sugiérame una buena manera de hacerlo (incluida la verificación del éxito / falla de la copia y la verificación del tipo mimo). Si el archivo no tiene tipo mime, aparecerá un error con información detallada.
Aquí está el código:
$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();
}
Cuando hago esto, mi tipo mime se establece en application / x-empty
También parece que cuando el estado es diferente de 200, Guzzle lanzará automáticamente una excepción. ¿Cómo puedo detener este comportamiento y verificar el estado por mí mismo para poder enviar un mensaje de error personalizado?
EDITAR: Esto fue para Guzzle 3.X. Así es como puedes hacerlo usando Guzzle v 4.X (funciona también con 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'',
]);
O usando la corriente de 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());
Esto se ve muy bien. ¿Hay una solución mejor / adecuada al usar Guzzle 4?
Mira esto con el 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);
Aquí debes enviar la solicitud de tu "post".
y con get
$myFile = fopen(''path/to/file'', ''w'') or die(''Problems'');
$client = new /GuzzleHttp/Client();
$request = $client->get(''https://www.yourdocumentpage.com'', [''save_to'' => $myFile]);
y aquí no necesita enviar la solicitud, y here encontrará mucha documentación, debe tener guzzle 6 para hacer eso, y si está utilizando GOUTTE al mismo tiempo necesitará goutte 3.1, actualización tu requieres en tu compositor.json
Su código se puede simplificar mucho. El código de mi ejemplo a continuación transmitirá el cuerpo de la respuesta directamente al sistema de archivos.
<?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;
}
}
Cuando hago esto, mi tipo mime se establece en application / x-empty
¿Un tipo de archivo mimetype?
También parece que cuando el estado es diferente de 200, Guzzle lanzará automáticamente una excepción. ¿Cómo puedo detener este comportamiento y verificar el estado por mí mismo para poder enviar un mensaje de error personalizado?
Guzzle lanzará una excepción para las malas respuestas como 4xx y 5xx. No hay necesidad de deshabilitar esto. Solo atrapa una excepción y resuelve el error allí.
usando Guzzle 6 solo usa la opción SINK. ver a continuación la función detallada
Extra:
utilizar GuzzleHttp / Client; Espacio de nombres de Guzzle incluido
$ access_token = si necesita autenticación, simplemente elimine esta opción
ReportFileDownloadException = excepción personalizada
/**
* 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"
);
}