Domanda
Lo scorso fine settimana ho cambiato webhosts per il mio sito web. Il server host ero su era un sistema operativo a 32-bit e quello mi sono trasferito a è a 64 bit. Inaspettatamente, alcuni dei miei script PHP ha iniziato dando risultati non corretti.
Nel mio caso le operazioni << e >> (spostamento bit) erano il colpevole. Ho finito per dover mascherare il risultato con 0xFFFFFFFF e quindi modificando il risultato negativo, se per farlo funzionare come prima.
Ci sono altri possibili problemi nei miei script PHP devo cercare?
Soluzione
E 'un linguaggio di alto livello, in modo da qualcosa di non-bit correlato (operatori bit a bit, Bitshift) sarà lo stesso.
Altri suggerimenti
manipolazione bit richiede particolare cura per rendere portabile tra sistemi / architetture.
In C, << e >> operazioni possono essere effettuate portatile utilizzando senza segno variabili, che rimuove i / Twos regole complimento per i numeri negativi.
Come regola generale, dont utilizzare le maschere di lunghezza fissa per la manipolazione di bit (come & e |). Questi sono dipendenti da architettura.
Eg. Ripristino gli ultimi 4 bit: il maschera 0xF0 funziona su un 8-bit architettura, ma non a 16 bit. I risultati saranno diversi (16 bit può avere altri bit impostati che non sono inclusi nella maschera).
Per superare questo problema, utilizzare il ~ dell'operatore. La maschera ~ 0xF equivale a 0xF0, ma lavorerà su qualsiasi Architettura. saranno ripristinati tutti i bit tranne l'ultima 4
strtotime si comporta diversamente a 64 bit. Da PHP.net:
Nota:
L'intervallo valido di un timestamp è tipicamente da Ven 13 Dic 1901 20:45:54 UTC a mar, 19 gen 2038 03:14:07 UTC. (Queste sono le date che corrispondono ai valori minimo e massimo per un intero con segno a 32 bit.) Inoltre, non tutte le piattaforme supportano i timestamp negativi, quindi l'intervallo di date può essere limitata a non prima del dell'epoca Unix. Ciò significa che ad esempio date precedenti al 1 gennaio, 1970 non funziona su Windows, alcune distribuzioni di Linux, e un paio di altri sistemi operativi. PHP 5.1.0 e versioni più recenti di superare questo limite però.
Per le versioni a 64 bit di PHP, l'intervallo valido di un timestamp è effettivamente infinito, come 64 bit possono rappresentare circa 293 miliardi anno in entrambe le direzioni.
Abbiamo avuto codice che stava facendo strtotime ( '0000-00-00') e ci aspettavamo il risultato di essere falsa, quando ci siamo trasferiti a 64 bit siamo tornati un intero negativo.
L'unico problema del vedrete quando si sono fatte valere a 32 bit rappresentazione binaria dei dati. Soprattutto perché PHP usa interi con segno, vedrete questioni hashing, generazione di chiavi, ecc ... quando esplicitamente colata a int con (int), i numeri> 2 ^ 32 andranno a capo, dove in quanto non avvolgere in un ambiente a 64 bit a meno che non sono> 2 ^ 64, naturalmente.
Esempio 4 vs 8 bit:
questioni di valore decimale:
0010 >> 1 = 0001 [ 1 dec ]
0000 0010 >> 1 = 0000 0001 [ 1 dec ]
Si tratta sia di produrre lo stesso risultato (decimale saggio), invece:
0100 << 1 = 1000 [ -8 dec ]
0000 0100 << 1 = 0000 1000 [ 16 dec ]
problemi di confezionamento:
1000 << 1 = 0000 [ 0 dec ]
0000 1000 << 1 = 0001 0000 [ 32 dec ]
Tutti interi / floating point ops saranno trattati come valori a 64 bit, quindi se il vostro risultato finale si basa su pezzi 32bit si dovrà compensare tale.
I risultati della divisione in virgola mobile saranno influenzati dalla crescita a 64 bit; quindi se si dispone di codice che fa qualcosa di stupido come confrontando i risultati della divisione in virgola mobile a costanti hardcoded, si aspettano la rottura.