Visite também: Currículo ·  Efetividade BR-Mac

O que é LinuxDownload LinuxApostila LinuxEnviar notícia


Tratamento de inteiros de 64 bits em PHP

Enviado por Marcus Vinicius (mvleandroΘgmail·com):

“”Estive diante de um desafio no qual eu precisava desenvolver a camada server-side de uma aplicação mobile rodando em Android. Toda a aplicação client-side já estava homologada e devidamente testada, ou seja, finalizada e não poderia sofrer alterações no código.

Esta aplicação client-side, para controlar a versão dos arquivos que recebe, precisa ler o conteúdo de um arquivo binário, que continha um número inteiro representando a data da versão no formato: Ymdhis.

O primeiro problema surgiu devido ao tamanho do inteiro. Para gravar um inteiro deste tamanho, por exemplo: 20100831120030, eu precisaria de pelo menos 45 bits, porém o PHP, até a atual versão, só grava números inteiros de 32 bits. Acima de 32 bits somente número de ponto flutuante. Precisamos converter o inteiro para 64 bits.

O segundo problema veio ao tentar gravar um número inteiro de 64 bits em um arquivo. As funções de manipulação de arquivo do PHP só trabalham com strings e não com inteiros. Se eu usasse uma função como file_put_contents, por exemplo, ela criaria um arquivo com 64KB em vez de 64b, pois interpretaria cada bit como um caractere, usando um byte para representar cada um, em vez de um bit. O que precisamos é que o conteúdo do arquivo seja exatamente: 00100100100100000010110111001100000101010011110 em binário e não a string correspondente a este binário.”

Veja mais em -> http://www.phpnaveia.com.br/artigo/salvando-um-numero-inteiro-de-64-bits-em-um-arquivo-binario/” [referência: phpnaveia.com.br]


• Publicado por Augusto Campos em 2010-09-01

Comentários dos leitores

Os comentários são responsabilidade de seus autores, e não são analisados ou aprovados pelo BR-Linux. Leia os Termos de uso do BR-Linux.

    devnull (usuário não registrado) em 1/09/2010 às 9:22 am

    Sempre que descubro algo novo sobre PHP, me decepciono um pouco mais.

    Marcus Vinicius (usuário não registrado) em 1/09/2010 às 10:07 am

    devnull Você tem o direito de se decepcionar, assim como tem o direito de permanecer na superficialidade/preconceitos sobre PHP.

    A versão 6 do PHP já vai trabalhar com inteiros de 64 bits. E PHP é uma linguagem poderosíssima.

    Já ouviu falar em FaceBook por exemplo? Não é feito em .Net nem em Java, nem em Python, tampouco em rails, é em PHP. É bom né? Rápido né?

    Abraço!

    É realmente necessário usar 64 bits? Eu usaria algum algorítimo para compactar a informação. Talvez converter a data para data Juliana. Um método fácil de entender segue abaixo.

    Veja como compactar a hora:

    his = precisa de 18 bits
    (h*60+i)*60+s = precisa de 16 bits

    Já a data, complica. Se vc limitá-la de 128 anos fica bem mais fácil, por exemplo, de 1900 a 2027, ou de 2000 a 2127. Daí:

    Y-m-d 9999-12-31 = precisa de 27 bits
    Y-m-d 2099-12-31 = precisa de 25 bits
    Y-m-d 2127-12-31 usando ((Y-2000)*13+m)*32+d = precisa de 16 bits

    Obs.: vi em alguns lugares que o cara usa na fórmula acima, o m-1 e o d-1 (para fazer o mês e o dia começarem do zero). Daí os fatores ficam *12 e *31, mas não vejo ganho de bits nisso.

    É claro que é muito importante escolher a faixa, pois não poderá armazer qq data que seja fora dela.

    Foo (usuário não registrado) em 1/09/2010 às 11:29 am

    Alguém já ouviu falar de timestamp?

    foobob (usuário não registrado) em 1/09/2010 às 12:51 pm

    independente de ser popular o bastante para criar a interface de usuário do Facebook, PHP é mais nojento e sem senso de estilo do que Perl (que traz ou trazia Amazon nas costas antes de reescreverem em C++).

    é trágico que o mundo de TI seja largamente escrito em linguagens precárias e horrendas como C/C++, Java, Perl, PHP e cia….

    Vin (usuário não registrado) em 1/09/2010 às 1:52 pm

    Talvez usar String? Ja’ que e’ um formato para parsear mesmo. um VARCHAR funciona.

    Vin (usuário não registrado) em 1/09/2010 às 1:55 pm

    Certo, li errado, esqueçam o comentário acima. Mas concordo com o uso de TIMESTAMP.

    Marcus Vinicius (usuário não registrado) em 1/09/2010 às 1:56 pm

    Se todos leram atentamente, podem compreender que a aplicação client-side não poderia ser mudada, ou seja, não poderia ser feito um parser. O código no programa feito para android, estava preparado para receber um inteiro de 64bit e finish. Nada poderia ser feito lá, somente no server-side, a fim de passar a informação no formato que o client entende.

    OBS: Alguém dá comida pro trolzinho foobob por favor. Ele deve estar com fome.

    Abçs!

    Marcus Vinicius (usuário não registrado) em 1/09/2010 às 2:01 pm

    Reforçando meu comentário anterior: Existem n maneiras diferentes de representar a data ( inclusive melhores ), mas a questão não é essa. O desafio era que a aplicação client-side não poderia ser mudada. E a solução encontrada para entregar a informação no formato que o client necessitava foi essa.

    Abraços!

    @foobob

    C/C++, Java, Perl, PHP etc linguagem precárias?

    Linux e Windows são escritos em C/C++. Aliás, praticamente qualquer SO é.

    Java precária? É a linguagem preferida de instiuições financeiras. Acha que os bancos brasileiros compartilham de sua opinião sobre a precariedade de Java?

    Acha que eles não entendem bem do que fazem?

    PHP? Precária? Facebook?

    Deixa eu advinhar… Você é programador Rails, não é??? Ou Python.

    Como será que advinhei??!!

    @Marcus Vinicius

    Só alimentei o foobob o suficiente pra ele não morrer de inanição.

    Mas não vou dar mais um quirela pra ele.

    Marcus Vinicius (usuário não registrado) em 1/09/2010 às 2:16 pm

    Senhores, não vamos alimentar os trolls. Basta clicar no link [troll/flame] no comentário. :) Alimentá-los é desviar o tempo de contribuição à comunidade em vão.

    Abçs!

    Rod (usuário não registrado) em 1/09/2010 às 3:35 pm

    O Foobob deve ser “programador” de HTML =P

    Bem, a coisa precisava mesmo ser gravada em disco? Tipo, se a aplicação era separada em cliente e servidor, em teoria isso permite que o modelo de armazenamento dos dados feitos pelo servidor seja transparente ao cliente. Desta forma a maneira como o servidor faz o armazenamento não importa, desde que o cliente receba e envie os dados da forma que conhece.

    Assim creio que no caso poderia ser utilizado outro mecanismo de armazenamento, talvez o timestamp, que usa só 32 bits mas só funcionará até 2038.

    Em c há uma estrutura (timespec) capaz de representar bem o timestamp em nanosegundos (!), e tem 64 bits, sendo 32 bits com o timestamp em segundos e um inteiro de 32 bits para os nanosegundos adicionais. Tal ideia pode ser utilizada para armazenar dados maiores ou mais precisos, além de ser facilmente “gravável” e recuperável da memória ou disco.

    Mas é sério que php não manipula dados de 64 bits? Eu nunca mexi com isso em php, mas vi que ele usa cópias das funções fwrite e fread do C, que, em teoria, permitem q vc grave o número de bytes que quiser. Se vc pegar a ideia acima, + a função pack() do php, talvez saia alguma coisa interessante tbm.

    Geralmente dados muito grandes não são bem suportados por sgbds como o mysql (até dá pra armazenar binários nele, mas a performance é horrível).

    O ruim do php é, ainda hj, sua performance. Adoro PHP e ela é uma das minhas linguagens favoritas, mas odeio sua biblioteca padrão imensa, procedural (e a falta do suporte a namespaces (antes do 5.3) ajuda a tornar a coisa pior), com nomes bizarros me assusta. Se tem uma coisa que eu mudaria no PHP é sua notação de array/coleção, que é muito “verbose”.

    Entendo que a ideia foi interessante para este caso específico, mas não ficou muito elegante não :-)

    sorry, na primeira linha do meu comentário anterior, substitua a palavra disco por arquivo (embora tudo no fim seja arquivo e disco :-))

    Ah sim, pra quem quer trabalhar com coisas que dependem do tamanho de dados em C e C++ e quer não depender da plataforma, use os inteiros do arquivo stdint.h. Sizeof(int) nunca é uma boa ideia, mas sizeof(int32_t) é, além de mais enxuto (uint64_t é bem melhor que unsigned long long (em 32 bits), por exemplo).

    foobob (usuário não registrado) em 2/09/2010 às 1:32 am

    André Luis Pereira dos Santos em 1/09/2010 às 2:13 pm
    “Linux e Windows são escritos em C/C++. Aliás, praticamente qualquer SO é.”

    é justo por isso que o que mais se tem ainda hoje são bugs e falhas de segurança devidos a buffer overflows. Precário, além da hedionda e convoluta sintaxe/semântica…

    “Java precária? É a linguagem preferida de instiuições financeiras. Acha que os bancos brasileiros compartilham de sua opinião sobre a precariedade de Java?”

    Java não peca pela precariedade, mas pelo extremo oposto. Eu diria que peca por “camadas overflow”…

    “PHP? Precária? Facebook?”

    PHP é só pra geração do html. Todos os processos backend que fazem a coisa toda mover são C/C++ ou Java. Menos precário, mas ainda horrendo…

    “Deixa eu advinhar… Você é programador Rails, não é??? Ou Python.”

    quem dera! Sou programador Delphi, PHP nas horas vagas e uma ou outra contribuição open-source em C. Não discuto com patrão sobre suas preferências! Não quer dizer que não consiga ter o bom senso e visão crítica suficiente para perceber que são ferramentas realmente primitivas e deploráveis…

    Quisera eu viver em um mundo escrito em python, haskell ou ocaml…

Este post é antigo (2010-09-01) e foi arquivado. O envio de novos comentários a este post já expirou.