2012-12-31 34 views
0

我在運行Mac和Linux的PHP代碼中遇到不同的輸出。PHP和Apache2中的奇怪行爲:不同服務器中的不同輸出

我有2個服務器上運行以下代碼:

$ltt = ((ord($str[7]) << 24) | (ord($str[8]) << 16) | (ord($str[9]) << 8) | (ord($str[10])))/1000000; 

即使ord(str[ ])輸出是相同的:

[7] = 254 
[8] = 26 
[9] = 22 
[10] = 216 

但是,運行PHP 5.3.6的MAMP棧上(Mac),如果$ ltt最初應該是負數,則返回4263.12265(不正確)。

在運行相同php版本的LAMP棧(Ubuntu)上,它將返回確切的負值-31.84465

出現這種情況只能用負數..

更新ADDL。信息:

  • 甲變種轉儲給出þØçï_Kstring(25) "þØçï_K"
  • BIN2HEX給出000e1b00000000fe1a16d806e707ef0000045f0000004b0000

Simplying功能爲只包括數字輸入,輸出仍然不同

$ltt = (254 << 24 | 26 << 16 | 22 << 8 | 216)/ 1000000; 

4263.12265在MAMP上和-31.84465在L上AMP

+0

兩臺機器的PHP配置是否相同?相同的版本並不總是意味着相同的設置;) – Kevin

+1

是一個64位和其他32位?我不認爲它實際上*應該*在這裏雖然... ... – Charles

+0

這兩個都是32位,配置是股票,除了一些內存限制和post_Data的變化.. – kouton

回答

4

這是32位和64位的問題。

由於您的最高有效字節大於127,因此在32位平臺上,由於整數溢出,會將其解釋爲負值 - 設置最高有效位。在64位平臺上它不是。

解決方案是使用pack()unpack(),因此您可以指定該整數應該被簽名。 編輯 修正此代碼示例 見編輯2

$packed = pack('C*', ord($str[7]), ord($str[8]), ord($str[9]), ord($str[10])); 
$unpacked = unpack('l', $packed); 
$lat = current($unpacked); 

...但是你也應該意識到,這將不是一個小端架構的工作,因爲它的字節順序將是錯誤的。你可以簡單地顛倒打包字節的順序來解決這個問題,但我只是想把自己的頭圍繞在一個無處不在的解決方案中。

EDIT 2

OK,我花了一段時間來環繞此我的頭,但我們最終到了那裏:

你需要做的是,如果最顯著位或者將結果與一個數字進行比較,其中最不重要的32位沒有被設置,其餘的都是。所以下面的32位和64位工作:

<?php 

// The input bytes as ints 
$bytes = array(254, 26, 22, 216); 

// The operand to OR with at the end 
$op = $bytes[0] & 0x80 ? (~0 << 16) << 16 : 0; 

// Do the bitwise thang 
$lat = (($bytes[0] << 24) | ($bytes[1] << 16) | ($bytes[2] << 8) | $bytes[3]) | $op; 

// Convert to float for latitude 
$lat /= 1000000; 

echo $lat; 
+0

@ÁlvaroG.Vicario我只知道這一點的確定性,因爲我對示例字節進行了數學計算,結果如下。 MAMP棧是64位的。但是,我提出的解決方案代碼是錯誤的:-(現在開始工作,但是如果您有解決方案,我很樂意提高它,因爲它還很早,我的心理二進制計算器還沒有正常工作。 – DaveRandom

+0

感謝您的回答..我仍然得到0作爲輸出 – kouton

+0

@Reddox 32/64位問題是明確的,我的解決方案是錯誤的。我現在正在處理它,我可能需要先喝茶,所以如果有人在我之前到達那裏你可能應該接受, – DaveRandom

相關問題