今天说说PHP8中的数字类型,就是整型和浮点型,我们常说的数字类型,大都指的是十进制,计算机中还有二进制,八进制,十六进制,其中二进制也是常用的类型,十六进制一般只在CSS颜色值中用到过,八进制基本没怎么用到过,了解一下也是可以的。
//来自php文档: https://www.php.net/manual/zh/language.types.integer.php
$a = 1234; // 十进制数
$a = 0123; // 八进制数 (等于十进制 83)
$a = 0o123; // 八进制数 (PHP 8.1.0 起)
$a = 0x1A; // 十六进制数 (等于十进制 26)
$a = 0b11111111; // 二进制数字 (等于十进制 255)
$a = 1_234_567; // 整型数值 (PHP 7.4.0 以后) 值就是 1234567
数字类型在PHP中是用途很广,上篇文章已经说道,数字类型和bool类型之间是可以自动转换的,这里再提一下,数字字符串也可以自动转成数字类型的,int和flot的转换需要手动处理,否则会报Deprecated错误,看以下例子:
class Number
{
public function getNumberFromNull(null $a): int{
return (int)$a; //需要转换,否则报错
}
public function getNumberFromBool(bool $a): int{
return $a;
}
public function getIntFromString(string $a): int{
return $a;
}
public function getFloatFromString(string $a): float{
return $a;
}
public function getNumberFromOthers(array|callable|object $a): int{
//callable和object会报 PHP Warning ..
return (int)$a;
}
}
$number = new Number();
//var_dump($number->getNumberFromNull(null));//报错
var_dump($number->getNumberFromBool(false));//输出 0
var_dump($number->getNumberFromBool(true));//输出 1
var_dump($number->getIntFromString('123'));//输出 123
var_dump($number->getIntFromString(123));//输出 123
var_dump($number->getIntFromString('123.123'));//输出 123.123 (Deprecated 错误)
var_dump($number->getIntFromString(123.34));//输出 123.34 (Deprecated 错误)
//var_dump($number->getIntFromString('12aa'));//Fatal error
var_dump($number->getFloatFromString('123.123'));//输出 123.123
var_dump($number->getFloatFromString(123.34));//输出 123.34
var_dump($number->getNumberFromOthers([]));//输出 0
var_dump($number->getNumberFromOthers([1,2,3]));//输出 1
var_dump($number->getNumberFromOthers(new stdClass()));//输出 1 (PHP Warning)
var_dump($number->getNumberFromOthers(function (){}));//输出 1 (PHP Warning)
对浮点数的处理,需要注意精度问题,看以下例子:
//浮点数
var_dump((int)( (0.1+0.7) * 10 ));//输出7,而不是8
var_dump(round(( (0.1+0.7) * 10 )));//输出8
var_dump(0.1+0.2);//输出 0.30000000000000004
var_dump(0.1+0.2 == 0.3);//输出false
var_dump(0.1+0.2 >= 0.3);//输出true
对于二进制的应用,现在已经是很常见,比如在判断权限的时候,就非常有用,比如一个小模块,有很多权限项,需要跟前端整合,这个时候可以定义一个permission字段给前端,包含所有需要的权限,如下:
//二进制应用
class ModulePerm
{
const PERM_JONI = 1; // 0b00001
const PERM_CLOSE = 2; // 0b00010
const PERM_QUIT = 4; // 0b00100
const PERM_SET_ADMIN = 8; // 0b01001
const PERM_CAN_ADMIN = 16; // 0b10000
//....
public function getPermission(): int{
$perm = $this->getJoinPerm();
//$perm += ....
//....
return $perm;
}
public function hasPermission(int $perm): bool{
return $perm & $this->getPermission();
}
protected function getJoinPerm(): int{
//...判断是否有这个权限
return static::PERM_JONI;
}
}
类中常量也可以定义为二进制,我喜欢用十进制,看着方便,也容易理解,也方便加减,如果可以后台控制,也可以将其存入数据库,一个字段即可搞定,可以往上累加。
最后说下int和float常用的函数,还是举例说明下:
//常用函数
var_dump((int)'11a');//输出 11
var_dump(intval('11a'));//输出 11
var_dump((float)'11a');//输出 11
var_dump(floatval('11.87'));//输出 11.87
var_dump((is_numeric('11.345')));//输出 true
var_dump(max(1, 5, 2));//输出 5
var_dump(min(1, 5, 2));//输出 1
var_dump(floor(2.8));//输出 2
var_dump(round(2.5));//输出 3
var_dump(ceil(2.1));//输出 3
代码放在: https://github.com/leo-up/php-study/blob/master/base/number.php