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



有时我会把头撞到墙上,因为这个。

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 支持全自动类型转换,在某些情况下执行手动转换的需求非常令人沮丧且有点愚蠢(要么所有类型都应该是可互换的,要么用户必须在所有类型之间执行转换本身)。

有什么想法吗?

要求boolord本质上是没有意义的。ord需要一个字符串,因此将任何输入强制转换为字符串。true投到'1'false投到'''1'ord49,空字符串的ord0

这并不意味着truefalse就是这样定义的true定义为truefalse定义为false。这只是您偶然发现的类型转换规则(是的,它们可以说是晦涩难懂的)。大多数数据库都支持本机布尔类型,或者只要您正确使用该 API,它们的 PHP 数据库 API 就会将 PHP 布尔值转换为数据库的等效值。

至于为什么存在这些铸造规则:

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

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

不,没有比这更有意义的了。

您的部分困惑是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

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

您是否正在尝试解决数据库查询问题?

最新更新