2012-12-31 29 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

相关问题