为什么PHP和JavaScript在处理八进制和十六进制数时有问题?

min*_*gos 11 javascript php hex casting octal

我注意到PHP和JavaScript处理八进制和十六进制数字时遇到一些困难,同时键入juggling和cast:

PHP:

echo 16 == '0x10' ? 'true' : 'false'; //true, as expected
echo 8  == '010'  ? 'true' : 'false'; //false, o_O

echo (int)'0x10';    //0, o_O
echo intval('0x10'); //0, o_O
echo (int)'010';     //10, o_O
echo intval('010');  //10, o_O
Run Code Online (Sandbox Code Playgroud)

JavaScript的:

console.log(16 == '0x10' ? 'true' : 'false'); //true, as expected
console.log(8  == '010'  ? 'true' : 'false'); //false, o_O

console.log(parseInt('0x10')); //16, as expected
console.log(parseInt('010'));  //8, as expected
console.log(Number('0x10'));   //16, as expected
console.log(Number('010'));    //10, o_O
Run Code Online (Sandbox Code Playgroud)

我知道,PHP有octdec()hexdec()功能补救八进制/十六进制的不当行为,但是我希望在intval()对付八进制和十六进制数,就像JavaScript的parseInt()一样.

无论如何,这种奇怪行为背后的理由是什么?

Nik*_*kiC 9

想象一下有人指定035一些产品的数量(领先0只是填充,所以它匹配列表中的其他三位数量).035显然可以解释35为非程序员.但是如果PHP要解释字符串中的八进制数字,结果会突然变成29=> WTF?!?另一方面,十六进制表示法不是问题,因为人们通常不使用0x23表示法指定数字.

顺便说一句,这不仅发生在最终用户身上,也发生在程序员身上.程序员经常尝试用前导零填充他们的数字 - 呵呵,一切都错了!这就是为什么JS不再允许在严格模式下使用八进制表示法,而其他语言使用更明确的0o前缀.

顺便说一句,我确实同意这种行为是不一致的.在我看来,十六进制表示法也不应该被解析.就像八进制和二进制表示法一样.特别是考虑到显式转换(int)也不解析十六进制,而只是读取所有内容直到第一个非数字.


解决这个问题intval,它实际上就像记录的一样:intval不是用于解析PHP的本机整数表示法,而是用于解析指定基数的整数.如果您查看文档,您会发现它需要$base默认的第二个参数10.((int)通过内部方式转换为同一个convert_to_long_base调用base = 10,所以它总是表现得很像intval.)