"Gotchas" da 32 a 64 bit in PHP

Lo scorso fine settimana ho cambiato i webhost per il mio sito web. Il server host su cui ero era un sistema operativo a 32 bit e quello a cui mi sono trasferito è 64 bit. Inaspettatamente, alcuni dei miei script PHP hanno iniziato a dare risultati errati.

Nel mio caso le operazioni << e >> (bit shift) erano il colpevole. Ho finito per wherer mascherare il risultato con 0xFFFFFFFF e poi modificare il risultato se negativo per farlo funzionare come prima.

Ci sono altri possibili problemi nei miei script PHP che dovrei cercare?

È un linguaggio di alto livello, quindi qualsiasi cosa non correlata ai bit (operatori bit a bit, bitshift) sarà la stessa.

Un numero integer può essere a 64 bit anziché a 32 bit. Ci sono alcuni casi bizzarri in cui ciò potrebbe causare problemi.

la manipolazione del bit richiede un'attenzione speciale per rendere porttile tra sisthemes / architetture.

In C, le operazioni << e >> possono essere rese porttili utilizzando variables non firmate , che rimuovono le regole di complimenti one / twos per i numbers negativi.

Come regola generale, non utilizzare maschere di lunghezza fissa per la manipolazione dei bit (come & e |). Questi sono dipendenti dall'architettura.

Per esempio. Ripristino degli ultimi 4 bit: la maschera 0xF0 functionrà su un'architettura a 8 bit, ma non a 16 bit. I risultati saranno diversi (a 16 bit potrebbero essere presenti altri bit che non sono inclusi nella maschera).

Per superare questo problema, utilizzare l'operatore ~. La maschera ~ 0xF è equivalente a 0xF0, ma functionrà su qualsiasi architettura. Tutti i bit tranne gli ultimi 4 verranno ripristinati

strtotime si comport diversamente su 64 bit. Da PHP.net:

Nota:

L'intervallo valido di un timestamp è in genere 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 minimi e massimi per un integer con segno a 32 bit.) Inoltre, non tutte le piattaforms supportno i timestamp negativi, pertanto l'intervallo di date potrebbe essere limitato a non prima dell'epoca Unix. Ciò significa che, ad esempio, date precedenti al 1 gennaio 1970 non functionranno su Windows, alcune distribuzioni Linux e alcuni altri sisthemes operativi. PHP 5.1.0 e versioni più recenti però superano questa limitazione.

Per le versioni a 64 bit di PHP, l'intervallo valido di un timestamp è effettivamente infinito, in quanto 64 bit possono rappresentare circa 293 miliardi di anni in entrambe le direzioni.

Avevamo il codice che stava facendo strtotime ('0000-00-00') e mi aspettavo che il risultato fosse falso, quando siamo passati a 64 bit abbiamo ottenuto un integer negativo.

L'unico problema che vedrai è quando ti sei affidato alla rappresentazione binaria a 32 bit dei dati. Soprattutto perché PHP usa interi con segno, vedrai problemi in Hashing, generazione di chiavi, ecc … quando si esegue il casting esplicito su int con (int), i numbers> 2 ^ 32 si avvolgeranno where non verranno avvolti in un ambiente a 64 bit a less che non siano> 2 ^ 64, naturalmente.

Esempio 4 vs 8 bit:

Problemi con valori decimali:

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

Entrambi producono lo stesso risultato (decimale saggio), tuttavia:

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

Problemi di avvolgimento:

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

Tutti i numbers interi / in virgola mobile verranno trattati come valori a 64 bit, quindi se il risultato finale si basa su blocchi a 32 bit, sarà necessario compensare tale valore.

I risultati della divisione in virgola mobile saranno influenzati dall'aumento a 64-bit; quindi se avete codice che fa qualcosa di stupido come confrontare i risultati della divisione in virgola mobile con costanti hardcoded, aspettatevi che si rompa.