2009-05-26 21 views
77

Estoy buscando una manera simple 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).Copie la imagen del servidor remoto a través de HTTP

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 enlazar la imagen en caliente, sino importarla y publicarla desde mi dominio.

+0

No tienen módulos servidores proxy para esto? – jiggunjer

Respuesta

142

Si tiene PHP5 y la envoltura de flujos HTTP habilitado en su servidor, es increíblemente fácil copiarla en un archivo local:

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

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

+29

Recuerde allow_url_fopen tiene que ser = on en php.ini. –

+3

El comentario allow_url_fopen acaba de resolverse en una hora de scratch. Gracias, @ mauro.dec! –

+2

¿Qué se está usando con URLs como esta 'http: // desmond .imageshack.us/Himg100/scaled.php? server = 100 & filename = desertoh.jpg & res = crop' ??? – zhilevan

0

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

Al utilizar PHP, puede usar curl para descargar archivos del otro servidor.

2

Es extremadamente simple usando file_get_contents. Simplemente proporcione la url como primer parámetro.

+1

Esto está bloqueado en los 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 los hosts que bloquean fopen en sistemas de archivos remotos. – Oli

+0

si cURL está disponible, eso sería aún mejor. ver cUrl at php.net PatrikAkerstrand

7

Tienes sobre estas cuatro posibilidades:

  • Remote files. Esto necesita allow_url_fopen para ser habilitado en php.ini, pero es el método más fácil.

  • Alternativamente, podría usar cURL si su instalación de PHP lo admite. Incluso hay un example.

  • Y si realmente desea hacerlo manualmente, utilice HTTP module.

  • Ni siquiera intentes a use sockets directly.

+0

¿Por qué el "No intentes usar enchufes directamente"? (Que es lo que estoy usando, https://gist.github.com/0893a7ec908ff508aac6) – Gajus

+0

@Gajus: No estás usando sockets directamente en ese fragmento. Está utilizando la capacidad de php para abrir archivos remotos. –

4

Aquí 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ás haciendo montones y montones de esto (o sus bloques alojar el archivo de acceso a sistemas remotos), considerar el uso de CURL, que es más eficiente, levemente más rápido y disponible en más hosts compartidos.

¡También puede suplantar al 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); 

En ambos casos, es posible que desee pasarlo a GD para asegurarse de que realmente se trata de una imagen.

+1

Para verificar la imagen con GD, considere ejecutar esto justo después de guardar el archivo: http://www.psoug.org/snippet/Check_if_an_image_exists_GD_364.htm - si se vuelve falso, elimine el archivo inmediatamente. – Oli

+2

Te perdiste 'curl_exec ($ ch)' antes de 'curl_close ($ ch)', y 'fclose ($ ch)' debe colocarse al final en lugar de antes 'curl_close ($ ch)', eso significa cerrar el archivo antes no se ha escrito nada en el archivo, por lo tanto, solo obtendrá un archivo vacío. –

0

Dado que ha etiquetado su pregunta 'php', asumiré que está ejecutando php en su servidor. Su mejor apuesta es si usted controla su propio servidor web, luego compila 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 habilitada esta opción.

Aquí está el php man page on using cURL. En los comentarios, puede encontrar un ejemplo de las descargas y el archivo de imagen.

Si no desea utilizar libcurl, puede codificar algo usando fsockopen. Está integrado en php (pero puede estar deshabilitado en su host), y puede leer y escribir directamente en sockets. Ver Examples on the fsockopen man page.

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.

+2

usando curl es un buen método porque algunos servidores no admiten el archivo_get_contents por razones de seguridad –

+1

Sugerencia agradable para archivos pequeños, pero para archivos más grandes la memoria php explotará :( curl tampoco es una buena opción, porque no es parte de php estándar – Radon8472

2

carpeta de marca y el nombre de ejemplo enemigo descarga bloc de notas abierta e inserte el código

único cambio http://www.google.com/aa.zip a su archivo y guardarlo en m.php por ejemplo

chamod el archivo php a 666 y la descarga carpeta 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 entrar a estos URL http://www.example.com/download/m.php

verá en la carpeta de descarga la descarga de archivos desde otro servidor

gracias

26

uso

$imageString = file_get_contents("http://example.com/image.jpg"); 
$save = file_put_contents('Image/saveto/image.jpg',$imageString); 
+0

gracias hombre !! la segunda solución está funcionando ... la mejor solución no funciona para mí: p – Rajnish

+4

Buen consejo para archivos pequeños, pero para archivos más grandes la memoria php explotará :( – Radon8472

0

He intentado copiar/descargar archivos remotos utilizando la función de copia behint un proxy, pero copiar se conecta directamente sin proxy.

Traté de establecer mi configuración como contexto predeterminado y la di como 3. parámetro de función para copiar.

Pero parece que el contexto nunca se usa, pero readfile o get_headers usan el mismo contexto.

tope aquí tienes mi código:

$url = "http://myserver.com/testfile"; 
$context_opts = array(
    "http" => array(
     "proxy" => "tcp://myProxy:8080", 
     "request_fulluri" => True, 
     "ignore_errors" => true 
    ) 
); 

stream_context_get_default($context_opts); 
print_r(get_headers($url,1)); 

copy($url,$filename, stream_context_create($context_opts)); 

Mi servidor se está ejecutando con:

  • Windows XP SP3
  • Apache 2.2.12 (que se ejecuta como servicio)
  • PHP 5.3. 0 (API20090626, TS, VC6) (configurado como módulo apache)

urlfopen está habilitado http y https streams están registrados para php

-2

This answer 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> 
+1

lea la pregunta antes de publicar la respuesta. – Steeve

0

Para aquellos que necesitan para preservar el nombre de archivo original y la extensión

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

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

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

copy($origin, $dest); 
Cuestiones relacionadas