php - servidor - html boton descargar archivo
Descarga el archivo al servidor desde la URL (10)
Bueno, este parece bastante simple, y lo es. Todo lo que tienes que hacer para descargar un archivo a tu servidor es:
file_put_contents("Tmpfile.zip", file_get_contents("http://someurl/file.zip"));
Sólo hay un problema. ¿Qué pasa si tienes un archivo grande, como 100 MB. Entonces, se quedará sin memoria y no podrá descargar el archivo.
Lo que quiero es una forma de escribir el archivo en el disco mientras lo estoy descargando. De esa manera, puedo descargar archivos más grandes, sin tener problemas de memoria.
- Cree una carpeta llamada "descargas" en el servidor de destino
- Guarde [este código] en el archivo
.php
y ejecútelo en el servidor de destino
Descargador:
<html>
<form method="post">
<input name="url" size="50" />
<input name="submit" type="submit" />
</form>
<?php
// maximum execution time in seconds
set_time_limit (24 * 60 * 60);
if (!isset($_POST[''submit''])) die();
// folder to save downloaded files to. must end with slash
$destination_folder = ''downloads/'';
$url = $_POST[''url''];
$newfname = $destination_folder . basename($url);
$file = fopen ($url, "rb");
if ($file) {
$newf = fopen ($newfname, "wb");
if ($newf)
while(!feof($file)) {
fwrite($newf, fread($file, 1024 * 8 ), 1024 * 8 );
}
}
if ($file) {
fclose($file);
}
if ($newf) {
fclose($newf);
}
?>
</html>
Arriba hay un ejemplo (citado por prodigitalson) del código que no funciona (razón: falta de fopen en CURLOPT_FILE - http://www.webdeveloper.com/forum/showthread.php?268299-RESOLVED-PHP-script-for-a-cronjob-download-file-unpzck-run-another-php-script ). No puedo agregar comentarios allí porque tengo un número demasiado bajo de puntos, por lo que a continuación doy un ejemplo de trabajo (también funciona para "url local"):
function downloadUrlToFile($url, $outFileName)
{
if(is_file($url)) {
copy($url, $outFileName);
} else {
$options = array(
CURLOPT_FILE => fopen($outFileName, ''w''),
CURLOPT_TIMEOUT => 28800, // set this to 8 hours so we dont timeout on big files
CURLOPT_URL => $url
);
$ch = curl_init();
curl_setopt_array($ch, $options);
curl_exec($ch);
curl_close($ch);
}
}
Desde PHP 5.1.0, file_put_contents()
admite la escritura pieza por pieza pasando un identificador de flujo como el parámetro $data
:
file_put_contents("Tmpfile.zip", fopen("http://someurl/file.zip", ''r''));
Del manual:
Si los datos [que es el segundo argumento] son un recurso de flujo, el búfer restante de ese flujo se copiará al archivo especificado. Esto es similar con el uso de
stream_copy_to_stream()
.
(Gracias .)
Hay 3 maneras:
- file_get_contents y file_put_contents
- RIZO
- Fopen
Puedes encontrar ejemplos desde aquí .
Intenta usar cURL
set_time_limit(0); // unlimited max execution time
$options = array(
CURLOPT_FILE => ''/path/to/download/the/file/to.zip'',
CURLOPT_TIMEOUT => 28800, // set this to 8 hours so we dont timeout on big files
CURLOPT_URL => ''http://remoteserver.com/path/to/big/file.zip'',
);
$ch = curl_init();
curl_setopt_array($ch, $options);
curl_exec($ch);
curl_close($ch);
No estoy seguro, pero creo que con la opción CURLOPT_FILE
escribe mientras extrae los datos, es decir. no amortiguado.
Utilice un método simple en la copy()
PHP copy()
copy($source_url, $local_path_with_file_name);
Nota: si el archivo de destino ya existe, se sobrescribirá
Nota especial: No olvide configurar el permiso 777 para la carpeta de destino
Yo uso esto para descargar el archivo
function cURLcheckBasicFunctions()
{
if( !function_exists("curl_init") &&
!function_exists("curl_setopt") &&
!function_exists("curl_exec") &&
!function_exists("curl_close") ) return false;
else return true;
}
/*
* Returns string status information.
* Can be changed to int or bool return types.
*/
function cURLdownload($url, $file)
{
if( !cURLcheckBasicFunctions() ) return "UNAVAILABLE: cURL Basic Functions";
$ch = curl_init();
if($ch)
{
$fp = fopen($file, "w");
if($fp)
{
if( !curl_setopt($ch, CURLOPT_URL, $url) )
{
fclose($fp); // to match fopen()
curl_close($ch); // to match curl_init()
return "FAIL: curl_setopt(CURLOPT_URL)";
}
if ((!ini_get(''open_basedir'') && !ini_get(''safe_mode'')) || $redirects < 1) {
curl_setopt($ch, CURLOPT_USERAGENT, ''"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.11) Gecko/20071204 Ubuntu/7.10 (gutsy) Firefox/2.0.0.11'');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($ch, CURLOPT_REFERER, ''http://domain.com/'');
if( !curl_setopt($ch, CURLOPT_HEADER, $curlopt_header)) return "FAIL: curl_setopt(CURLOPT_HEADER)";
if( !curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $redirects > 0)) return "FAIL: curl_setopt(CURLOPT_FOLLOWLOCATION)";
if( !curl_setopt($ch, CURLOPT_FILE, $fp) ) return "FAIL: curl_setopt(CURLOPT_FILE)";
if( !curl_setopt($ch, CURLOPT_MAXREDIRS, $redirects) ) return "FAIL: curl_setopt(CURLOPT_MAXREDIRS)";
return curl_exec($ch);
} else {
curl_setopt($ch, CURLOPT_USERAGENT, ''"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.11) Gecko/20071204 Ubuntu/7.10 (gutsy) Firefox/2.0.0.11'');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($ch, CURLOPT_REFERER, ''http://domain.com/'');
if( !curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false)) return "FAIL: curl_setopt(CURLOPT_FOLLOWLOCATION)";
if( !curl_setopt($ch, CURLOPT_FILE, $fp) ) return "FAIL: curl_setopt(CURLOPT_FILE)";
if( !curl_setopt($ch, CURLOPT_HEADER, true)) return "FAIL: curl_setopt(CURLOPT_HEADER)";
if( !curl_setopt($ch, CURLOPT_RETURNTRANSFER, true)) return "FAIL: curl_setopt(CURLOPT_RETURNTRANSFER)";
if( !curl_setopt($ch, CURLOPT_FORBID_REUSE, false)) return "FAIL: curl_setopt(CURLOPT_FORBID_REUSE)";
curl_setopt($ch, CURLOPT_USERAGENT, ''"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.11) Gecko/20071204 Ubuntu/7.10 (gutsy) Firefox/2.0.0.11'');
}
// if( !curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true) ) return "FAIL: curl_setopt(CURLOPT_FOLLOWLOCATION)";
// if( !curl_setopt($ch, CURLOPT_FILE, $fp) ) return "FAIL: curl_setopt(CURLOPT_FILE)";
// if( !curl_setopt($ch, CURLOPT_HEADER, 0) ) return "FAIL: curl_setopt(CURLOPT_HEADER)";
if( !curl_exec($ch) ) return "FAIL: curl_exec()";
curl_close($ch);
fclose($fp);
return "SUCCESS: $file [$url]";
}
else return "FAIL: fopen()";
}
else return "FAIL: curl_init()";
}
Una solución PHP 4 y 5:
readfile () no presentará ningún problema de memoria, incluso al enviar archivos grandes, por su cuenta. Se puede usar una URL como nombre de archivo con esta función si se han habilitado las envolturas de fopen.
private function downloadFile($url, $path)
{
$newfname = $path;
$file = fopen ($url, ''rb'');
if ($file) {
$newf = fopen ($newfname, ''wb'');
if ($newf) {
while(!feof($file)) {
fwrite($newf, fread($file, 1024 * 8), 1024 * 8);
}
}
}
if ($file) {
fclose($file);
}
if ($newf) {
fclose($newf);
}
}
set_time_limit(0);
$file = file_get_contents(''path of your file'');
file_put_contents(''file.ext'', $file);