Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

aleex995

Como faço isso ?

Recommended Posts

Olá galera, este é o meu primeiro post aqui no fórum...então vamos lá, queria saber como faço para transformar o código abaixo que tá 100.00 MB para 1 GB.

 

function convertsize($size,$mode=0)
{
  $times = 0;
  $comma = '.';
  while ($size>1024){
     $times++;
     $size = $size/1024;
  }
  $size2 = floor($size);
  $rest = $size - $size2;
  $rest = $rest * 100;
  $decimal = floor($rest);

  $addsize = $decimal;
  if ($decimal<10) {$addsize .= '0';};

  if ($times == 0){$addsize=$size2;} else
  {$addsize=$size2.$comma.substr($addsize,0,2);}

  switch ($times) {
     case 0 : $mega = " Byte"; break;
     case 1 : $mega = " KB"; break;
     case 2 : $mega = " MB"; break;
     case 3 : $mega = " GB"; break;
     case 4 : $mega = ' TB'; break;
  }
  if($mode==1&&(($pos=strrpos($addsize,'.')))!==false)$addsize=substr($addsize,0,$pos);
  $addsize .= $mega;
  return $addsize;
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fiquei mais de 1 hora fazendo, mas acho que ficou 10:

 

<?php
/**
* Converts bytes to the appropriate notation
* @author Matheus Tavares <contato at matheustavares . com . br>
* @param int $bytes
* @return string
*/
function convert ( $bytes ) {
$notation =	array( '','K','M','G','T','P','E','Z','Y' );
for( $i = 0 , $size = sizeof( $notation ) ; $i < $size ; $i++ )
	if ( ( $bytes = $bytes >> 10 * ( (int)($i!==0) ) ) >> 10 < 1 )
		return sprintf( '%d %s' , $bytes , $notation[ $i ] . 'Bytes' );
}

 

Basta você entregar o tamanho do arquivo em bytes, que a função faz o resto. Exemplos:

 

printf(
'%s<br />%s<br />%s<br />%s',
convert( 1024 ),//Retorno: 1 KBytes
convert( 1024 * 5 ),//Retorno: 5 KBytes
convert( 35 << (10*2) ),//Retorno: 35 MBytes
convert( 1 << (10*3) )//Retorno: 1 GBytes
);

 

Daí vamos supor que você queira saber quanto pesa um arquivo qualquer... você faz assim:

$arquivo = 'arquivo.txt';
echo convert( filesize( $arquivo ) );

 

[]'s!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Nos comentários do Manual sobre filesize() e disk_free_space() por exemplo, tem trocentos códigos de conversão de unidades.

 

No manual tem uns ridiculamente grandes, já o do Matheus é um bem pequeno e vai direto ao ponto.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ótima solução Matheus, pelo visto eu preciso estudar mais, dificilmente entendo esses operadores binários. :X

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fiquei mais de 1 hora fazendo, mas acho que ficou 10:

...

 

Desse jeito aqui em baixo eu acho que fica mais simples e mais facil de entender:

 

<?php
function convert ( $bytes ) {
$notation =	array( '','K','M','G','T','P','E','Z','Y' );
for( $i = 0 , $size = sizeof( $notation ) ; $i < $size ; $i++ )
	if ( $bytes < 1024 )
		return sprintf( '%d %s' , $bytes , $notation[ $i ] . 'Bytes' );
	else
		bytes >>= 10;
}

 

Dá pra fazer como uma função recursiva também:

 

<?php
function convert ( $bytes, $i = 0 ) {
$notation =	array( '','K','M','G','T','P','E','Z','Y' );
return ($bytes < 1024 || $i >= sizeof($notation)) ?
	sprintf( '%d %s' , $bytes , $notation[ $i ] . 'Bytes' ) :
	convert($bytes >> 10, $i + 1);
}

Talvez essa recursiva fique melhor usando lista ao invés de array.

 

É possivel também substituir o ">> 10" por "/ 1024", ai dá pra tratar numeros de ponto flutuante.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado à todos, pessoal.

O Matheus Izvekov é um excelente engenheiro da computação, e muito do que aprendi com binários devo à ele. A solução com recursividade ficou interessante por dar maior simplicidade, sem aumentar o número de linhas. Show!

Mas enfim, espero que tenha ajudado o autor do tópico.

[]'s!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fiquei mais de 1 hora fazendo, mas acho que ficou 10:

 

<?php
/**
* Converts bytes to the appropriate notation
* @author Matheus Tavares <contato at matheustavares . com . br>
* @param int $bytes
* @return string
*/
function convert ( $bytes ) {
$notation =	array( '','K','M','G','T','P','E','Z','Y' );
for( $i = 0 , $size = sizeof( $notation ) ; $i < $size ; $i++ )
	if ( ( $bytes = $bytes >> 10 * ( (int)($i!==0) ) ) >> 10 < 1 )
		return sprintf( '%d %s' , $bytes , $notation[ $i ] . 'Bytes' );
}

 

Basta você entregar o tamanho do arquivo em bytes, que a função faz o resto. Exemplos:

 

printf(
'%s<br />%s<br />%s<br />%s',
convert( 1024 ),//Retorno: 1 KBytes
convert( 1024 * 5 ),//Retorno: 5 KBytes
convert( 35 << (10*2) ),//Retorno: 35 MBytes
convert( 1 << (10*3) )//Retorno: 1 GBytes
);

 

Daí vamos supor que você queira saber quanto pesa um arquivo qualquer... você faz assim:

$arquivo = 'arquivo.txt';
echo convert( filesize( $arquivo ) );

 

[]'s!

 

Obrigado cara! irei aplicar isso.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fiz uma versão com algumas melhorias, permitindo agora o ponto flutuante no retorno, e a especificação de precisão.

 

<?php
/**
* Converts bytes to the appropriate notation
* @author Matheus Tavares <contato at matheustavares . com . br>
* @param int $bytes
* @return string
*/
function convert ( $bytes, $precision = 2 , $i = 0 ) {
$notation = array( '','K','M','G','T','P','E','Z','Y' );
return ( $bytes < 1024 )
	? sprintf( '%.'.$precision.'F %s' , $bytes , $notation[ $i ] . 'B' )
	: convert( $bytes / 1024 , $precision , $i + 1 );
}

# Exemplos:
printf(
'%s<br>%s<br>%s<br>%s',
convert( 37643878.4 , 0 ),//Retorno: 36 MB
convert( 37643878.4 , 1 ),//Retorno: 35.9 MB
convert( 37643878.4 , 2 ),//Retorno: 35.90 MB
convert( 37643878.4 , 3 ) //Retorno: 35.900 MB
);

 

[]'s

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fiz uma versão com algumas melhorias, permitindo agora o ponto flutuante no retorno, e a especificação de precisão.

 

<?php
/**
* Converts bytes to the appropriate notation
* @author Matheus Tavares <contato at matheustavares . com . br>
* @param int $bytes
* @return string
*/
function convert ( $bytes, $precision = 2 , $i = 0 ) {
$notation = array( '','K','M','G','T','P','E','Z','Y' );
return ( $bytes < 1024 )
	? sprintf( '%.'.$precision.'F %s' , $bytes , $notation[ $i ] . 'B' )
	: convert( $bytes / 1024 , $precision , $i + 1 );
}

# Exemplos:
printf(
'%s<br>%s<br>%s<br>%s',
convert( 37643878.4 , 0 ),//Retorno: 36 MB
convert( 37643878.4 , 1 ),//Retorno: 35.9 MB
convert( 37643878.4 , 2 ),//Retorno: 35.90 MB
convert( 37643878.4 , 3 ) //Retorno: 35.900 MB
);

 

[]'s

 

Como voce tirou o teste com o sizeof do array, agora a funcao pode ter um comportamento nao especificado, ou tacar uma excecao (como n sou experiente com php, nao sei qual dos dois) caso o valor do argumento seja grande o suficiente. Anteriormente ela iria imprimir um valor maior que 1024 na maior unidade especificada no array. Nao sei se voce fez isso conscientemente.

 

Uma propriedade util dessa funcao recursiva eh que ela expoe o 'i' como parametro, e ele pode ser aproveitado pra dar a opcao do usuario especificar uma unidade de entrada.

Por exemplo, voce pode ter um enum definindo:

Byte = 0

KiloByte = 1

MegaByte = 2

...

(Estou digitando no telefone, nao me dei ao trabalho de escrever o codigo)

 

Com isso o usuario, se tiver por exemplo uma variavel que esta em outra unidade sem ser bytes, pode chamar a funcao diretamente, sem precisar converter pra bytes primeiro.

Por exemplo:

converte(2048, 0, KiloByte); // retorna 2MB

Compartilhar este post


Link para o post
Compartilhar em outros sites
Como voce tirou o teste com o sizeof do array, agora a funcao pode ter um comportamento nao especificado, ou tacar uma excecao (como n sou experiente com php, nao sei qual dos dois) caso o valor do argumento seja grande o suficiente.

Pô, não vejo a menor possibilidade de alguém fazer uma validação de um arquivo maior que alguns Gigabytes, quem diria Yotabytes... A validação só geraria processamento à toa, por isso a retirei.

 

Quanto à dica do enum, realmente é uma boa!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendi. Mas se usar essa funcao com um argumento controlado por um agente externo,

eh possivel que isso seja utilizado como algum exploit, dependendo do comportamento do php

em relacao a bounds checking do array. Na pior das hipoteses, isso pode ser usado para ler uma posicao arbitraria da memoria, como por exemplo uma chave de seguranca ou uma senha.

 

De qualquer forma, se voce acha isso desnecessario, poderia ter omitido essa checagem na sua versao com loop for tambem.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.