¿Hay alguna forma de obtener el tamaño de un archivo remoto http://my_url/my_file.txt sin descargar el archivo?PHP: Tamaño de archivo remoto sin descargar el archivo
Respuesta
encontrado algo sobre este here:
Ésta es la mejor manera (que he encontrado) para obtener el tamaño de un archivo remoto . Tenga en cuenta que las solicitudes HEAD no obtienen el cuerpo real de la solicitud, , solo recuperan los encabezados. Entonces hacer una solicitud HEAD a un recurso que es 100MB tomará la misma cantidad de tiempo que una solicitud HEAD a un recurso que es 1KB.
<?php
/**
* Returns the size of a file without downloading it, or -1 if the file
* size could not be determined.
*
* @param $url - The location of the remote file to download. Cannot
* be null or empty.
*
* @return The size of the file referenced by $url, or -1 if the size
* could not be determined.
*/
function curl_get_file_size($url) {
// Assume failure.
$result = -1;
$curl = curl_init($url);
// Issue a HEAD request and follow any redirects.
curl_setopt($curl, CURLOPT_NOBODY, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_USERAGENT, get_user_agent_string());
$data = curl_exec($curl);
curl_close($curl);
if($data) {
$content_length = "unknown";
$status = "unknown";
if(preg_match("/^HTTP\/1\.[01] (\d\d\d)/", $data, $matches)) {
$status = (int)$matches[1];
}
if(preg_match("/Content-Length: (\d+)/", $data, $matches)) {
$content_length = (int)$matches[1];
}
// http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
if($status == 200 || ($status > 300 && $status <= 308)) {
$result = $content_length;
}
}
return $result;
}
?>
Uso:
$file_size = curl_get_file_size("http://stackoverflow.com/questions/2602612/php-remote-file-size-without-downloading-file");
Sure. Realice una solicitud de solo encabezados y busque el encabezado Content-Length
.
Dado que esta cuestión ya está etiquetada "php" y "rizar", estoy asumiendo que usted sabe cómo utilizar Curl en PHP.
Si configura curl_setopt(CURLOPT_NOBODY, TRUE)
, entonces hará una solicitud HEAD y probablemente verifique el encabezado "Content-Length" de la respuesta, que será solo encabezados.
probar este código
function retrieve_remote_file_size($url){
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_NOBODY, TRUE);
$data = curl_exec($ch);
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
curl_close($ch);
return $size;
}
Pruebe la función de abajo para obtener el tamaño del archivo remoto
function remote_file_size($url){
$head = "";
$url_p = parse_url($url);
$host = $url_p["host"];
if(!preg_match("/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/",$host)){
$ip=gethostbyname($host);
if(!preg_match("/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/",$ip)){
return -1;
}
}
if(isset($url_p["port"]))
$port = intval($url_p["port"]);
else
$port = 80;
if(!$port) $port=80;
$path = $url_p["path"];
$fp = fsockopen($host, $port, $errno, $errstr, 20);
if(!$fp) {
return false;
} else {
fputs($fp, "HEAD " . $url . " HTTP/1.1\r\n");
fputs($fp, "HOST: " . $host . "\r\n");
fputs($fp, "User-Agent: http://www.example.com/my_application\r\n");
fputs($fp, "Connection: close\r\n\r\n");
$headers = "";
while (!feof($fp)) {
$headers .= fgets ($fp, 128);
}
}
fclose ($fp);
$return = -2;
$arr_headers = explode("\n", $headers);
foreach($arr_headers as $header) {
$s1 = "HTTP/1.1";
$s2 = "Content-Length: ";
$s3 = "Location: ";
if(substr(strtolower ($header), 0, strlen($s1)) == strtolower($s1)) $status = substr($header, strlen($s1));
if(substr(strtolower ($header), 0, strlen($s2)) == strtolower($s2)) $size = substr($header, strlen($s2));
if(substr(strtolower ($header), 0, strlen($s3)) == strtolower($s3)) $newurl = substr($header, strlen($s3));
}
if(intval($size) > 0) {
$return=intval($size);
} else {
$return=$status;
}
if (intval($status)==302 && strlen($newurl) > 0) {
$return = remote_file_size($newurl);
}
return $return;
}
Este es el único que funcionó para mí en Ubuntu Linux Apache Server. Tuve que iniciar $ size y $ status al comienzo de la función, de lo contrario funcionaba como está. –
mayoría de las respuestas aquí utiliza ya sea CURL o están basando en las cabeceras de lectura. Pero en algunas situaciones determinadas puede usar una solución mucho más fácil. Considere la nota en filesize()
's docs on PHP.net. Encontrarás un consejo que dice: "A partir de PHP 5.0.0, esta función también se puede utilizar con algunos contenedores de URL. Consulta Supported Protocols and Wrappers para determinar qué envoltorios admiten la familia de funcionalidades de stat()".
Por lo tanto, si su servidor y analizador PHP están configurados correctamente, puede simplemente usar la función filesize()
, alimentarla con URL completa, señalar un archivo remoto, qué tamaño desea obtener y dejar que PHP haga toda la magia.
El IMPLEMENTACIÓN más simple y más eficiente:
function remote_filesize($url) {
static $regex = '/^Content-Length: *+\K\d++$/im';
if (!$fp = @fopen($url, 'rb')) {
return false;
}
if (
isset($http_response_header) &&
preg_match($regex, implode("\n", $http_response_header), $matches)
) {
return (int)$matches[0];
}
return strlen(stream_get_contents($fp));
}
Funcionó como magia. Gracias. – rottenoats
No estoy seguro, pero no podía utilizar la función get_headers para esto?
$url = 'http://example.com/dir/file.txt';
$headers = get_headers($url, true);
if (isset($headers['Content-Length'])) {
$size = 'file size:' . $headers['Content-Length'];
}
else {
$size = 'file size: unknown';
}
echo $size;
Con este ejemplo, es posible que el servidor de destino en $ url explote get_headers para mantener la conexión abierta hasta que el proceso de PHP agote el tiempo (devolviendo los encabezados muy lentamente, aunque no lo suficientemente lento como para dejar la conexión obsoleta). Como los procesos totales de PHP pueden estar limitados por FPM, esto puede permitir un tipo de ataque de loris lento cuando múltiples "usuarios" acceden a su secuencia de comandos get_headers simultáneamente. –
Como se ha mencionado un par de veces, el camino a seguir es para recuperar la información de Content-Length
campo de la cabecera de respuesta.
Sin embargo, debe tener en cuenta que
- el servidor que está sondeando no necesariamente pone en práctica el método HEAD (!)
- no hay absolutamente ninguna necesidad de elaborar manualmente una petición HEAD (que, de nuevo, no podría incluso ser compatible) usando
fopen
o similar o incluso para invocar la librería curl, cuando PHP tieneget_headers()
(recuerda: K.I.S.S.)
El uso de get_headers()
sigue el K.I.S.S. principley funciona incluso si el servidor que está sondeando no admite la solicitud HEAD.
tanto, aquí está mi versión (truco: devuelve el tamaño legible con formato ;-)):
Síntesis: https://gist.github.com/eyecatchup/f26300ffd7e50a92bc4d (rizo y get_headers versión)
get_headers() - Versión:
<?php
/**
* Get the file size of any remote resource (using get_headers()),
* either in bytes or - default - as human-readable formatted string.
*
* @author Stephan Schmitz <[email protected]>
* @license MIT <http://eyecatchup.mit-license.org/>
* @url <https://gist.github.com/eyecatchup/f26300ffd7e50a92bc4d>
*
* @param string $url Takes the remote object's URL.
* @param boolean $formatSize Whether to return size in bytes or formatted.
* @param boolean $useHead Whether to use HEAD requests. If false, uses GET.
* @return string Returns human-readable formatted size
* or size in bytes (default: formatted).
*/
function getRemoteFilesize($url, $formatSize = true, $useHead = true)
{
if (false !== $useHead) {
stream_context_set_default(array('http' => array('method' => 'HEAD')));
}
$head = array_change_key_case(get_headers($url, 1));
// content-length of download (in bytes), read from Content-Length: field
$clen = isset($head['content-length']) ? $head['content-length'] : 0;
// cannot retrieve file size, return "-1"
if (!$clen) {
return -1;
}
if (!$formatSize) {
return $clen; // return size in bytes
}
$size = $clen;
switch ($clen) {
case $clen < 1024:
$size = $clen .' B'; break;
case $clen < 1048576:
$size = round($clen/1024, 2) .' KiB'; break;
case $clen < 1073741824:
$size = round($clen/1048576, 2) . ' MiB'; break;
case $clen < 1099511627776:
$size = round($clen/1073741824, 2) . ' GiB'; break;
}
return $size; // return formatted size
}
Uso:
$url = 'http://download.tuxfamily.org/notepadplus/6.6.9/npp.6.6.9.Installer.exe';
echo getRemoteFilesize($url); // echoes "7.51 MiB"
Nota adicional: El encabezado Content-Length es opcional. Por lo tanto, como una solución general no es a prueba de balas!
Esta debería ser la respuesta aceptada. Es cierto que 'Content-Length' es opcional, pero es la única forma de obtener el tamaño del archivo sin descargarlo, y' get_headers' es la mejor forma de obtener 'content-length'. –
Aquí hay otro enfoque que trabajará con los servidores que no soportan HEAD
solicitudes.
Utiliza cURL para realizar una solicitud del contenido con un encabezado de rango HTTP que solicita el primer byte del archivo.
Si el servidor admite solicitudes de rango (la mayoría de los servidores de medios lo harán), recibirá la respuesta con el tamaño del recurso.
Si el servidor no responde con un rango de bytes, buscará un encabezado de longitud de contenido para determinar la longitud.
Si el tamaño se encuentra en un rango o un encabezado de longitud de contenido, la transferencia se cancela. Si no se encuentra el tamaño y la función comienza a leer el cuerpo de la respuesta, la transferencia se cancela.
Esto podría ser un enfoque suplementario si una solicitud HEAD
da como resultado una respuesta no compatible con el método 405
.
/**
* Try to determine the size of a remote file by making an HTTP request for
* a byte range, or look for the content-length header in the response.
* The function aborts the transfer as soon as the size is found, or if no
* length headers are returned, it aborts the transfer.
*
* @return int|null null if size could not be determined, or length of content
*/
function getRemoteFileSize($url)
{
$ch = curl_init($url);
$headers = array(
'Range: bytes=0-1',
'Connection: close',
);
$in_headers = true;
$size = null;
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2450.0 Iron/46.0.2450.0');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0); // set to 1 to debug
curl_setopt($ch, CURLOPT_STDERR, fopen('php://output', 'r'));
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $line) use (&$in_headers, &$size) {
$length = strlen($line);
if (trim($line) == '') {
$in_headers = false;
}
list($header, $content) = explode(':', $line, 2);
$header = strtolower(trim($header));
if ($header == 'content-range') {
// found a content-range header
list($rng, $s) = explode('/', $content, 2);
$size = (int)$s;
return 0; // aborts transfer
} else if ($header == 'content-length' && 206 != curl_getinfo($curl, CURLINFO_HTTP_CODE)) {
// found content-length header and this is not a 206 Partial Content response (range response)
$size = (int)$content;
return 0;
} else {
// continue
return $length;
}
});
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data) use ($in_headers) {
if (!$in_headers) {
// shouldn't be here unless we couldn't determine file size
// abort transfer
return 0;
}
// write function is also called when reading headers
return strlen($data);
});
$result = curl_exec($ch);
$info = curl_getinfo($ch);
return $size;
}
Uso:
$size = getRemoteFileSize('http://example.com/video.mp4');
if ($size === null) {
echo "Could not determine file size from headers.";
} else {
echo "File size is {$size} bytes.";
}
función de PHP get_headers()
obras para que compruebe la de longitud de contenido como
$headers = get_headers('http://example.com/image.jpg', TRUE);
$filesize = $headers['content-length'];
Para más detalle: PHP Function get_headers()
Para mí (con nginx) el encabezado era Content-Length – Pangamma
una línea mejor solución:
echo array_change_key_case(get_headers("http://.../file.txt",1))['content-length'];
php es demasiado delicius
function urlsize($url):int{
return array_change_key_case(get_headers($url,1))['content-length'];
}
echo urlsize("http://.../file.txt");
- 1. php: descargar contenido variable como archivo
- 2. ¿Cómo puedo conservar el nombre del archivo remoto al descargar un archivo utilizando rizo
- 3. Griales descargar el archivo
- 4. curl obtener archivo remoto y descargar fuerza al mismo tiempo
- 5. PHP obtener archivo remoto mime-tipo
- 6. incluyendo un archivo remoto en PHP
- 7. etiquetas ID3 Leer sin necesidad de descargar el archivo completo
- 8. ¿La forma más fácil de capturar el tamaño del archivo remoto en PHP?
- 9. Guarde el archivo img remoto en el servidor, con php
- 10. cargar un archivo remoto para Google Drive
- 11. No se puede obtener el nombre de archivo remoto en file_get_contents() y luego almacenar el archivo
- 12. Descargar el archivo CSV usando "AJAX"
- 13. FtpWebRequest Descargar archivo
- 14. Descargar archivo - VB6
- 15. ¿Cómo puedo saber si un archivo en un FTP es idéntico a un archivo local sin realmente descargar el archivo?
- 16. PHP tamaño de archivo sobre 4Gb
- 17. PHP include(): Tamaño y rendimiento del archivo
- 18. Tamaño de imagen remota sin descargar
- 19. Descargar archivo dentro de WebView
- 20. grails descargar archivo
- 21. Cargar archivo xml remoto
- 22. Descargar archivo único
- 23. HTTP Descargar archivo muy grande
- 24. Descargar el archivo pdf de la wikipedia
- 25. Descargar el archivo url de datos
- 26. Descargar archivo a través de una llamada ajax php
- 27. Seguridad PHP: recuperar el archivo PHP del servidor, sin procesar
- 28. ¿Cómo descargar un archivo de SFTP usando PHP?
- 29. Cómo usar HttpWebRequest para descargar el archivo
- 30. Descargar archivo utilizando el servicio WCF Rest?
i estaba leyendo que antes, no estaba seguro de si el contenido de longitud significaba que el tamaño de la longitud o archivo – dassouki
bien si la solicitud devuelve un archivo, el tamaño de la solicitud * es * el tamaño del archivo – Gareth
Pero tenga en cuenta que _can_ pueden haber respuestas sin Longitud del contenido. – VolkerK