settype() 只接受变量(lvalue),不能用于表达式、函数返回值等右值;(int)最快,intval()支持进制,settype()修改原变量;"0"转布尔为false是PHP特殊规则;浮点转整数均会丢精度,金融计算应避免浮点。

为什么 settype() 改不了变量类型?
因为 settype() 是「就地修改」,它操作的是变量本身,但如果你传的是表达式、函数返回值或数组元素(非变量),PHP 会报 Warning: settype(): Cannot set type on expression。这不是 bug,是设计限制——它只接受变量(lvalue)。
常见踩坑场景:
- 写
settype($arr[0], 'int')—— 没问题,$arr[0]是可写的变量 - 写
settype(foo(), 'string')—— 直接报错,foo()是右值(rvalue) - 写
settype($obj->prop, 'bool')—— PHP 8.0+ 允许,但老版本可能失败,建议先赋给临时变量再转
(int) 和 intval() 到底选哪个?
三者都能转整数,但行为差异明显:(int) 是强制类型转换,不调用任何函数;intval() 是函数调用,支持进制参数;settype() 修改原变量并返回布尔结果。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 要「取整数值」且不关心原变量:优先用
(int),最快最轻量 - 要按进制解析(比如十六进制字符串
"1a"):必须用intval($str, 16) - 要明确知道转换是否成功,并复用原变量:用
settype($var, 'int'),但记得检查返回值是否为true - 别用
intval("123abc")期待报错——它静默截断,返回123;想严格校验请用filter_var($str, FILTER_VALIDATE_INT)
字符串转布尔时,"0" 居然变成 false?
这是 PHP 最常被吐槽的隐式转换陷阱:(bool)"0" 结果是 false,而 (bool)"1"、(bool)"false"、(bool)"0.0" 全是 true。原因在于 PHP 的「空字符串和字符串 "0"」被特殊列为 falsy 值。
安全做法:
- 不要依赖
(bool)$str判断非空——改用strlen($str) > 0或$str !== '' - 若真要转布尔且需语义清晰(比如配置开关),显式比对:
$enabled = ($config_value === 'true' || $config_value == 1) -
filter_var($str, FILTER_VALIDATE_BOOLEAN)更可靠,它把"1"、"true"、"on"、"yes"视为true,其余(含"0")为false,且支持NULL_ON_FAILURE
浮点数转整数时,round()、floor()、(int) 哪个不丢精度?
没有一个「不丢精度」——浮点数本身在二进制中就是近似存储。但三者截断逻辑不同,直接影响结果:
-
(int)3.9→3(向零截断,truncation) -
floor(3.9)→3,floor(-3.9)→-4(向下取整) -
round(3.5)→4(四舍五入,注意 PHP 默认使用「四舍六入五成双」规则) - 关键区别:
(int)不做任何舍入,直接砍掉小数部分;round()可能引发浮点误差放大,比如round(0.35 * 100)有时得34而非35(因0.35无法精确表示) - 金融计算务必避开浮点:用整数分单位存储,或用
bcmul()/bcadd()
类型转换不是万能胶,尤其在边界值、国际化输入、浮点运算里,稍不注意就会让 == 变成 === 都救不了的坑。



















