Existe-t-il un moyen d'obtenir la taille d'un fichier distant ? http://my_url/my_file.txt sans télécharger le fichier ?
J'ai lu ça tout à l'heure, je ne savais pas si content-length signifiait la longueur ou la taille du fichier
Existe-t-il un moyen d'obtenir la taille d'un fichier distant ? http://my_url/my_file.txt sans télécharger le fichier ?
J'ai trouvé quelque chose à ce sujet ici :
Voici la meilleure façon (que j'ai trouvée) d'obtenir la taille d'un fichier distant distant. Notez que les requêtes HEAD ne récupèrent pas le corps de la requête, elles récupèrent juste les en-têtes. Ainsi, faire une requête HEAD vers une ressource qui fait 100 Mo prendra le même temps qu'une requête HEAD vers une ressource de ressource qui fait 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;
}
?>
Utilisation :
$file_size = curl_get_file_size( "http://stackoverflow.com/questions/2602612/php-remote-file-size-without-downloading-file" );
J'ai lu ça tout à l'heure, je ne savais pas si content-length signifiait la longueur ou la taille du fichier
Essayez ce code
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;
}
Si cela ne fonctionne pas pour vous, vous pouvez ajouter curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
.
Comme il a été mentionné à plusieurs reprises, la solution consiste à récupérer les informations de l'en-tête de réponse Content-Length
champ .
Cependant, vous devez noter que
fopen
ou similaire ou même pour invoquer la bibliothèque curl, alors que PHP a get_headers()
(Souvenez-vous : K.I.S.S. )Utilisation de get_headers()
suit le Le principe K.I.S.S. et fonctionne même si le serveur que vous sondez ne prend pas en charge la requête HEAD.
Donc, voici ma version (gimmick : renvoie une taille formatée lisible par l'homme ;-)) :
Gist : https://gist.github.com/eyecatchup/f26300ffd7e50a92bc4d (version curl et get_headers)
get_headers()-Version :
<?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 <eyecatchup@gmail.com>
* @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
}
Utilisation :
$url = 'http://download.tuxfamily.org/notepadplus/6.6.9/npp.6.6.9.Installer.exe';
echo getRemoteFilesize($url); // echoes "7.51 MiB"
Note supplémentaire : L'en-tête Content-Length est facultatif. Ainsi, comme solution générale il n'est pas à l'épreuve des balles !
Cela devrait être la réponse acceptée. Vrai, Content-Length
est facultatif, mais c'est le seul moyen d'obtenir la taille du fichier sans le télécharger. get_headers
est le meilleur moyen d'obtenir content-length
.
Sachez que cela changera la préférence de la méthode de requête en HEAD dans toutes les requêtes HTTP suivantes pour ce processus PHP. Utilisez stream_context_create
pour créer un contexte séparé à utiliser pour l'appel à get_headers
(7.1+).
Puisque cette question est déjà étiquetée "php" et "curl", je suppose que vous savez comment utiliser Curl en PHP.
Si vous définissez curl_setopt(CURLOPT_NOBODY, TRUE)
vous ferez alors une demande HEAD et pourrez probablement vérifier l'en-tête "Content-Length" de la réponse, qui ne sera constituée que d'en-têtes.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.