Copiar imagen del servidor remoto a través de HTTP

81

Estoy buscando una forma sencilla de importar / copiar imágenes desde un servidor remoto a una carpeta local usando PHP. No tengo acceso FTP al servidor, pero se puede acceder a todas las imágenes remotas a través de HTTP (es decir, http://www.mydomain.com/myimage.jpg ).

Ejemplo de uso: un usuario desea agregar una imagen a su perfil. La imagen ya existe en la web y el usuario proporciona una URL directa. No deseo vincular la imagen, sino importar y servir desde mi dominio.

GiladG
fuente
¿No tienen los servidores módulos proxy para esto?
jiggunjer

Respuestas:

153

Si tiene PHP5 y el contenedor de flujo HTTP habilitado en su servidor, es increíblemente simple copiarlo en un archivo local:

copy('http://somedomain.com/file.jpeg', '/tmp/file.jpeg');

Esto se encargará de cualquier canalización, etc.que sea necesario. Si necesita proporcionar algunos parámetros HTTP, hay un tercer parámetro de 'contexto de transmisión' que puede proporcionar.

Ciaran McNulty
fuente
33
Recuerde que allow_url_fopen tiene que estar = activado en php.ini.
mauro.dec
3
El comentario allow_url_fopen acaba de resolverse después de una hora de rascarse la cabeza. ¡Gracias, @ mauro.dec!
Michael Stalker
2
¿Qué se están poniendo con URL como esta http://desmond.imageshack.us/Himg100/scaled.php?server=100&filename=desertoh.jpg&res=crop ???
Yuseferi
Gracias por esta respuesta, creo que casi he llegado. Cuando dices '/tmp/file.jpg', ¿a qué se refiere? La RAÍZ del servidor web ... (por ejemplo: / var / www / vhosts, etc.) o la raíz del sitio web: / httpdocs / ... ?? No puedo ver aparecer los archivos y tengo url-fopen en ON. !!
itsricky
1
No use https, solo http
edCoder
31

utilizar

$imageString = file_get_contents("http://example.com/image.jpg");
$save = file_put_contents('Image/saveto/image.jpg',$imageString);
dazzafact
fuente
¡¡gracias hombre!! la segunda solución está funcionando ... la primera solución no me funciona: p
Rajnish
4
Buen consejo para archivos pequeños, pero para archivos más grandes la memoria php explotará :(
Radon8472
10

PHP tiene una función incorporada file_get_contents (), que lee el contenido de un archivo en una cadena.

<?php
//Get the file
$content = file_get_contents("http://example.com/image.jpg");

//Store in the filesystem. $fp = fopen("/location/to/save/image.jpg", "w"); fwrite($fp, $content); fclose($fp); ?>

Si desea almacenar el archivo en una base de datos, simplemente use la variable $ content y no guarde el archivo en el disco.


fuente
2
usar curl es un buen método porque algunos servidores no admiten file_get_contents por razones de seguridad
Rinto George
1
Buen consejo para archivos pequeños, pero para archivos más grandes, la memoria php explotará :( curl tampoco es una buena opción, porque no forma parte del php estándar
Radon8472
7

Tienes estas cuatro posibilidades:

Georg Schölly
fuente
¿Por qué el "Ni siquiera intente usar sockets directamente"? (Que es lo que estoy usando, gist.github.com/0893a7ec908ff508aac6 )
Gajus
@Gajus: No estás usando sockets directamente en ese fragmento. Estás usando la capacidad de php para abrir archivos remotos.
Georg Schölly
4

Esta es la forma más básica:

$url = "http://other-site/image.png";
$dir = "/my/local/dir/";

$rfile = fopen($url, "r");
$lfile = fopen($dir . basename($url), "w");

while(!feof($url)) fwrite($lfile, fread($rfile, 1), 1);

fclose($rfile);
fclose($lfile);

Pero si está haciendo mucho, mucho de esto (o su host bloquea el acceso a archivos a sistemas remotos), considere usar CURL, que es más eficiente, ligeramente más rápido y está disponible en más hosts compartidos.

¡También puede falsificar el agente de usuario para que parezca un escritorio en lugar de un bot!

$url = "http://other-site/image.png";
$dir = "/my/local/dir/";
$lfile = fopen($dir . basename($url), "w");

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)');
curl_setopt($ch, CURLOPT_FILE, $lfile);

fclose($lfile);
curl_close($ch);

Con ambos casos, es posible que desee pasarlo a través de GD para asegurarse de que realmente sea una imagen.

Oli
fuente
1
Para verificar la imagen con GD, considere ejecutar esto justo después de guardar el archivo: psoug.org/snippet/Check_if_an_image_exists_GD_364.htm - si vuelve falso, elimine el archivo inmediatamente.
Oli
4
Se perdió curl_exec($ch)antes curl_close($ch)y fclose($ch)debe colocarse al final en lugar de antes curl_close($ch), eso significa cerrar el archivo antes de que no se haya escrito nada en el archivo, por lo tanto, solo obtendrá un archivo vacío.
Hendra Uzia
2

Es extremadamente simple usar file_get_contents . Simplemente proporcione la URL como primer parámetro.

PatrikAkerstrand
fuente
1
Esto está bloqueado en sistemas de archivos locales en muchos hosts compartidos por razones de seguridad. cURL es mejor, más rápido, más fuerte, etc. Y generalmente está disponible en aquellos hosts que bloquean fopen en sistemas de archivos remotos.
Oli
si cURL está disponible, sería aún mejor. ver <a href=" se2.php.net/curl"> cUrl en php.net </a>
PatrikAkerstrand
2

crear carpeta y nombrarla ejemplo de enemigo descargar libreta abierta e insertar este código

solo cambie http://www.google.com/aa.zip a su archivo y guárdelo en m.php, por ejemplo

chamod el archivo php a 666 y la carpeta de descarga a 777

<?php
define('BUFSIZ', 4095);
$url = 'http://www.google.com/aa.zip';
$rfile = fopen($url, 'r');
$lfile = fopen(basename($url), 'w');
while(!feof($rfile))
fwrite($lfile, fread($rfile, BUFSIZ), BUFSIZ);
fclose($rfile);
fclose($lfile);
?>

finalmente desde su navegador ingrese a estas URL http://www.example.com/download/m.php

Verá en la carpeta de descarga el archivo descargado desde otro servidor

Gracias

العاب فلاش
fuente
0

Utilice una solicitud GET para descargar la imagen y guardarla en un directorio accesible desde la web en su servidor.

Como está utilizando PHP, puede utilizar curlpara descargar archivos del otro servidor.

Peter Stuifzand
fuente
0

Como ha etiquetado su pregunta como 'php', asumiré que está ejecutando php en su servidor. Su mejor opción es si controla su propio servidor web, luego compile cURL en php. Esto permitirá que su servidor web realice solicitudes a otros servidores web. Esto puede ser bastante peligroso desde el punto de vista de la seguridad, por lo que la mayoría de los proveedores de alojamiento web básico no tendrán esta opción habilitada.

Aquí está la página de manual de php sobre el uso de cURL . En los comentarios puede encontrar un ejemplo que descarga un archivo de imagen.

Si no desea usar libcurl, puede codificar algo usando fsockopen. Esto está integrado en php (pero puede estar deshabilitado en su host) y puede leer y escribir directamente en sockets. Consulte Ejemplos en la página de manual de fsockopen .

Brianegge
fuente
0

Para aquellos que necesitan conservar el nombre de archivo y la extensión originales

$origin = 'http://example.com/image.jpg';

$filename = pathinfo($origin, PATHINFO_FILENAME);
$ext = pathinfo($origin, PATHINFO_EXTENSION);

$dest = 'myfolder/' . $filename . '.' . $ext;

copy($origin, $dest);
Marcio Mazzucato
fuente
-5

Esta respuesta me ayudó a descargar la imagen del servidor al lado del cliente.

<a download="original_file.jpg" href="file/path.jpg">
  <img src="file/path.jpg" class="img-responsive" width="600" />
</a>
Abduhafiz
fuente