Pergunta

Na semana passada eu mudei webhosts para o meu site. O servidor host que eu estava era um SO de 32 bits e aquele que me mudei para é de 64 bits. Inesperadamente, alguns dos meus scripts PHP começou a dar resultados incorretos.

No meu caso as operações << e >> (shift bit) eram o culpado. Acabei por ter de mascarar o resultado com 0xFFFFFFFF e em seguida, alterando o resultado se negativo para que ele funcione como fazia antes.

Existem quaisquer outros possíveis problemas em meus scripts PHP que devo procurar?

Foi útil?

Solução

É uma linguagem de alto nível, então qualquer coisa não-bit relacionado (operadores bit a bit, bitshift) será o mesmo.

Outras dicas

Um inteiro pode ser de 64 bits em vez de 32 bits. Há algumas bizarras casos onde isso pode causar problemas.

manipulação de bits requer um cuidado especial para tornar portátil entre sistemas / arquiteturas.

Em C, << e >> operações podem ser feitas portátil usando sem assinatura variáveis, que remove os / twos regras elogio para números negativos.

Como regra geral, uso não faça máscaras de comprimento fixo para manipulação de bits (como & e |). Estes são dependentes arquitetura.

Por exemplo. Repor os últimos 4 bits: o mascarar 0xF0 vai trabalhar em um 8-bit arquitetura, mas não de 16 bits. Os resultados serão diferentes (de 16 bits pode ter outros bits que são definidas que não são incluídos na máscara).

Para ultrapassar este problema, fazer uso do operador ~. A máscara ~ 0xF é equivalente a 0xF0, mas irá funcionar em qualquer arquitetura. Todos os bits, exceto o último 4 serão repostas

strtotime comporta de forma diferente em 64 bits. De PHP.net:

Nota:

O intervalo válido de um timestamp é tipicamente de Fri, 13 dez 1901 20:45:54 UTC para Tue, 19 jan 2038 03:14:07 UTC. (Estas são as que correspondem aos valores mínimo e máximo para um inteiro assinado de 32 bits.) Além disso, nem todas as plataformas suportam timestamps negativos, então o intervalo de datas pode ser limitada a não mais cedo do que a época Unix. Isto significa que, por exemplo, datas anteriores a 01 de janeiro de 1970 não irá funcionar no Windows, algumas distribuições Linux, e alguns outros sistemas operacionais. PHP 5.1.0 e versões mais recentes superar essa limitação embora.

Para versões do PHP de 64 bits, o intervalo válido de um timestamp é efetivamente infinito, como 64 bits pode representar cerca de 293.000 milhões ano em qualquer direção.

Tivemos código que estava fazendo strtotime ( '0000-00-00') e espera que o resultado seja falsa, quando nos mudamos para 64 bits voltamos um inteiro negativo.

O único problema é que você verá são quando você contou com 32-bit representação binária de dados. Principalmente porque o PHP usa inteiros assinados, você verá problemas em hash, geração de chaves, etc ... quando casting explicitamente para int com (int), números> 2 ^ 32 vai embrulhar onde, como eles não vão quebrar em um ambiente de 64 bits a menos que sejam> 2 ^ 64 é claro.

4 vs 8 exemplo bit:

Problemas valor decimal:

     0010 >> 1 =      0001   [ 1 dec ]
0000 0010 >> 1 = 0000 0001   [ 1 dec ]

Estes ambos produzem o mesmo resultado (decimal sábio), no entanto:

     0100 << 1 =      1000   [ -8 dec ]
0000 0100 << 1 = 0000 1000   [ 16 dec ]

problemas de acondicionamento:

     1000 << 1 =      0000   [  0 dec ]
0000 1000 << 1 = 0001 0000   [ 32 dec ]

Todos inteiro / flutuantes ops ponto será tratado como valores de 64 bits, por isso, se o seu resultado final depende de pedaços de 32 bits você vai ter que compensar tal.

Os resultados de divisão ponto flutuante será afectada pelo aumento de 64 bits; por isso, se você tiver o código que faz algo estúpido como comparar os resultados da divisão de ponto flutuante para constantes codificado, esperar que ele quebrar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top