aleex995 0 Denunciar post Postado Fevereiro 19, 2012 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
Matheus Tavares 167 Denunciar post Postado Fevereiro 19, 2012 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
Bruno Augusto 417 Denunciar post Postado Fevereiro 19, 2012 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
JCMais 75 Denunciar post Postado Fevereiro 19, 2012 Ó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
hinom 5 Denunciar post Postado Fevereiro 19, 2012 #4 dificilmente entendo esses operadores binários. :X :seta: Operadores bit-a-bit Compartilhar este post Link para o post Compartilhar em outros sites
JCMais 75 Denunciar post Postado Fevereiro 19, 2012 #4 :seta: Operadores bit-a-bit :clap: Estudarei o tópico. Valeu pelo link. Compartilhar este post Link para o post Compartilhar em outros sites
Matheus Izvekov 0 Denunciar post Postado Fevereiro 19, 2012 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
Matheus Tavares 167 Denunciar post Postado Fevereiro 19, 2012 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
aleex995 0 Denunciar post Postado Fevereiro 19, 2012 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
Matheus Tavares 167 Denunciar post Postado Fevereiro 19, 2012 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
Matheus Izvekov 0 Denunciar post Postado Fevereiro 20, 2012 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
Matheus Tavares 167 Denunciar post Postado Fevereiro 20, 2012 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
Matheus Izvekov 0 Denunciar post Postado Fevereiro 20, 2012 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