PHP中TRUE和FALSE常量定义之间的不一致

时间:2019-04-03 08:20:55

标签: php casting

因此,有时我会把头撞到墙上。

var_dump(ord(true), ord(false));

给予:

  

int(49)
  int(0)

因此,将TRUE转换为ASCII代码49-数字1,将FALSE转换为ASCII代码0(零字节)。 为什么在将TRUE / FALSE转换为字符串时会出现这种不一致?为什么不能将FALSE转换为ASCII码48-期望整数上下文的数字0(因为TRUE为'1')?

此类定义的最大问题是,如果将布尔值存储在某些变量中,然后将其保存在数据库中-则TRUE存储为'1',而FALSE存储为'-空字符串。因此,在存储到数据库中之前,您需要转换为整数(int)($bool_variable)。鉴于PHP支持全自动类型转换,因此在某些情况下执行手动强制转换的要求非常令人沮丧和愚蠢(所有类型都应可互换,或者用户必须自行执行强制转换在所有类型之间)。

有什么想法吗?

3 个答案:

答案 0 :(得分:5)

要求ord中的bool本质上是没有意义的。 ord需要一个字符串,因此将任何输入都强制转换为字符串。 true强制转换为'1',而false强制转换为''ord的{​​{1}}是'1',空字符串的49ord

这并不意味着0true如此定义。 false被定义为true,而true被定义为false。这只是您绊倒的类型转换规则(是的,它们可以说是不可思议的)。大多数数据库都支持本机布尔类型,或者只要您正确使用API​​,它们的PHP数据库API会将PHP布尔转换为数据库的等效布尔值。

关于为什么存在这些强制转换规则:

  

布尔值false转换为字符串TRUE。布尔值"1"将转换为FALSE(空字符串)。这样可以在布尔值和字符串值之间来回转换。

     

https://www.php.net/manual/en/language.types.string.php#language.types.string.casting

不,没有什么比这更有意义了。

答案 1 :(得分:4)

您可能会感到困惑的是,ord根本不是在此处使用的正确函数-它不是强制转换函数,也不是接受任何类型的调试函数。该函数需要一个字符串,并返回一个int,因此PHP必须首先将布尔值转换为字符串,然后运行该函数。

请注意,PHP 不会false转换为ASCII NUL字节(0)。那只是您在目的之外使用ord()的一种人工产物:您传递了一个空字符串,并询问“该字符串的第一个字节是什么?”可以说,它应该给您一个错误,但是在这种情况下,它决定给您0

最好使用var_dump,它用于检查PHP值:

var_dump(true); // bool(true)
var_dump(false); // bool(false)
var_dump((string)true); // string(1) "1"
var_dump((string)false); // string(0) ""

如果要将布尔值转换为选定的表示形式,最好的方法是使用三元运算符:

$bitAsInt = $booleanValue ? 1 : 0;
$bitAsString = $booleanValue ? '1' : '0';
$booleanKeyword = $booleanValue ? 'true' : 'false';
$boolString = $booleanValue ? "'t'" : "'f'";

以上所有内容在某些情况下都适用于某些数据库系统,并且很好地解释了为什么(string)$booleanValue不能每次都给您正确的东西。

在其他一些情况下,(string)false给出一个空字符串是最有用的,这就是PHP决定的。那就是:

(string)$booleanValue === ($booleanValue ? '1' : '')

“为什么”总是有很多答案。从历史的角度来看,这很可能是受Perl(在PHP创建时在Web编程中很流行)的启发-尽管它没有布尔类型,但确实表现出类似的转换行为:

print ( 1==1 ); # true as string, gives '1'
print ( 1==2 ); # false as string, gives ''
print 0 + ( 1==1 ); # true as int, gives 1
print 0 + ( 1==2 ); # false as int, gives 0

答案 2 :(得分:-1)

php将空字符串视为false。是否从数据库中读取。

您是否要解决数据库查询问题?