为什么php的字符串,为什么PHP认为0等于字符串?

我有以下代码:

$item['price'] = 0;

/*code to get item information goes in here*/

if($item['price'] == 'e') {

$item['price'] = -1;

}

它旨在将项目价格初始化为0,然后获取有关它的信息。 如果价格被告知为'e',则表示交易而不是卖出,卖出作为负数存储在数据库中。

还有可能将价格保留为0,因为该项目是奖金或因为价格将在稍后设定。

但是,只要没有设置价格,使其初始值为0,上面指出的if循环评估为真,价格设置为-1。 也就是说,它认为0等于'e'。

怎么解释这个?

编辑:

当价格提供为0(初始化后)时,行为不稳定:有时if评估为true,有时评估为false。

我发现使用triple ===而不是double ==给出了预期的行为。 但它仍然很奇怪。

(参考)在PHP手册的类型Juggling章节中充分说明,并在类型比较表中说明

如果唯一可能的字符串类型是e,你只能去一个is_string($ item ["price"])检查? 那会比===更有效率。 [引证需要]

在字符串和整数之间的弱比较中,字符串被转换为整数(而不是被"提升"为字符串的整数)。 if((string)$item[price] == e)修复了奇怪的行为。 有关更多详细信息,请参见stackoverflow.com/a/48912540/1579327

请注意以下评论中@Paolo的另一个案例,其中0(整数)等于使用double equals运算符时的任何其他字符串。

你正在做==,为你排序类型。

0是一个int,所以在这种情况下它会将'e'强制转换为int。哪个不可解析为一个,并将成为0。字符串'0e'将变为0,并且匹配!

使用===

松散比较的另一个缺点。

棘手的一个。 刚碰到这一个,并惊讶为什么字符串== 0.要记住。

当我循环使用字符串键时,我也在这个问题上摸不着头脑,但是数组有一个初始零索引项,在第一个字符串键比较时保持结果为true。 我是什么样的? 如何......所以,果然,这个答案清除了! 我很惊讶这整个问题没有一个接受的答案。 只是去展示一些问题,因为他们是混蛋。

这是由于PHP如何进行==比较运算符表示的比较操作:

If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. […] The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value.

由于第一个操作数是数字(0)而第二个操作数是字符串('e'),因此字符串也会转换为数字(另请参见表格与各种类型的比较)。字符串数据类型的手册页定义了字符串到数字转换的完成方式:

When a string is evaluated in a numeric context, the resulting value and type are determined as follows.

If the string does not contain any of the characters '.', 'e', or 'E' and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer. In all other cases it will be evaluated as a float.

在这种情况下,字符串是'e',因此它将被评估为float:

The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits.

由于'e'不是以有效的数字数据开头,因此它的计算结果为float 0。

php设计的大多数东西都很容易被比较,然后抛出几个陷阱只是为了毁了我们的一天。 这不符合PHP的其他设计理念。 除非欺骗有哲学???

特别是因为"e"演员为真,而且"演员都是假的

"ABC" == 0

计算true,因为第一个"ABC"转换为整数并变为0,然后将其与0进行比较。

这是PHP语言的奇怪行为:通常会将0提升为字符串"0",然后将"ABC"与结果false进行比较。

也许这就是其他语言中发生的情况,例如JavaScript,弱比较"ABC" == 0评估false。

进行严格的比较可以解决问题:

"ABC" === 0

评估false。

但是如果我需要将数字作为字符串与数字进行比较呢?

"123" === 123

评估false因为左右术语属于不同类型。

实际需要的是一个弱的比较,没有PHP类型杂耍的陷阱。

解决方案是明确地将术语提升为字符串,然后进行比较(严格或弱无关紧要)。

(string)"123" === (string)123

true

(string)"123" === (string)0

false

应用于原始代码:

$item['price'] = 0;

/*code to get item information goes in here*/

if((string)$item['price'] == 'e') {

$item['price'] = -1;

}

你的问题是双等号运算符,它将正确的成员类型化为左边的类型。如果您愿意,请使用strict。

if($item['price'] == 'e') {

$item['price'] = -1;

}

让我们回到你的代码(上面复制)。在这种情况下,在大多数情况下,$ item ['price']是一个整数(显然,除非它等于e)。因此,根据PHP的定律,PHP会将"e"类型转换为整数,从而产生int(0)。 (不相信我?)。

为了轻松摆脱这种情况,请使用三重相等(精确比较)运算符,它将检查类型并且不会隐式地进行类型转换。

P.S:一个有趣的PHP事实:a == b并不意味着b == a。举个例子并反过来:只要$ item ['price']总是一个整数,if ("e" == $item['price'])就永远不会实现。

==运算符将尝试匹配值,即使它们属于不同类型。例如:

'0' == 0 will be true

如果您还需要类型比较,请使用===运算符:

'0' === 0 will be false

在PHP中有一个非常方便的方法,用于验证混合的"0","假","关闭"为== false和"1","on","true"为== true,这经常被忽略。它对解析GET / POST参数特别有用:

filter_var( $item['price'], FILTER_VALIDATE_BOOLEAN );

它与这个用例没有多大关系,但鉴于相似性和事实,这是搜索结果,当询问验证(字符串)"0"为错误时,我认为它会帮助其他人。

http://www.php.net/manual/en/filter.filters.validate.php

您应该使用===而不是==,因为普通运算符不会比较类型。相反,它会尝试对项目进行类型转换。

同时===考虑项目的类型。

===表示"等于",

==表示"eeeeh ..有点像"

我知道了。 这现在有效(使用类型转换):if((string)$item[price]==e){ $item[price] = -1; }

但你不应该这样做。 只需使用===运算符

我认为最好通过我做的例子来展示,同时遇到同样奇怪的行为。查看我的测试用例,希望它能帮助您更好地理解行为:

//Normal comparison using the == Operator

echo (0 =="0"); // true

echo (0 =="a"); // true

echo (0 =="safta!"); //true

echo (1000 =="bla"); //false. It appears that PHP has a weird behavior only with the number / string 0 /"0" according to the past 3 examples.

echo (23 =="23"); //true. So as we said, PHP has a problem (not a problem but weird behavior) only when the number / string 0 (or"0") is present

echo (23 =="24"); //false. values aren't equal (unlike last example). type is less relevant with the == operator as we can see.

//now using the === and !== Operators

echo ("0" === 0); //false, since === requires both value and type to be the same. here, type is different (int vs string)

echo ("0" !== 0); //true because they aren't the same in terms of === comparison (type is different and that's why its true)

echo ("bla" ==="blaa"); //false because the values are not the same. The type is the same but === check for both equal type and equal value

//Now using casting and === Operator:

echo ((string)123 ==="123"); //true. The casting of the int 123 to string changed it to"123" and now both vars have same value and are of same type

echo ((int)"123" === 123); //true. The casting of the string 123 to int, changed it to int, and now both vars are of same value and type (which is exactly what the === operator is looking for)

//Now using casting and == Operator. Basically, as we've seen above, the == care less for the

//type of var, but more to the value. So the casting is less relevant here, because even

//without casting, like we saw earlier, we can still compare string to int with the == operator

//and if their value is same, we'll get true. Either way, we will show that:

echo ((string)123 =="123"); //true. The casting of the int 123 to string changed it to"123" and now both vars have same value and are of same type

echo ((int)"123" == 123); //true. The casting of the string 123 to int, changed it to int, and now both vars are of same value and type (which is exactly what the === operator is looking for)

希望能帮助到你。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值