有时我会把头撞到墙上,因为这个。
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 支持全自动类型转换,在某些情况下执行手动转换的需求非常令人沮丧且有点愚蠢(要么所有类型都应该是可互换的,要么用户必须在所有类型之间执行转换本身)。
有什么想法吗?
要求bool
的ord
本质上是没有意义的。ord
需要一个字符串,因此将任何输入强制转换为字符串。true
投到'1'
,false
投到''
。'1'
的ord
是49
,空字符串的ord
是0
。
这并不意味着true
和false
就是这样定义的。true
定义为true
,false
定义为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。是否从数据库中读取。
您是否正在尝试解决数据库查询问题?