1.背景
1.1组合支付支付方式过多,一一枚举过于繁琐,故采用此方案
2.使用
2.1 单种支付方式一一列举,现金=1/信用卡=2/储蓄卡=4/余额=8/扫码=16—-按照2的0次方/1次方等顺序排列
2.2 对应的现金+信用卡方式就是1+2=3,数据库支付方式字段存值为3
2.3如果想查出来所有订单里包含现金支付的订单 需要这样写 whereRaw(‘(pay_type & 1) > 0’)
2.4 如果想查出来这个订单都包含什么支付方式 需要这样写–返回数组[1,2,4]
function decomposeToPowersOfTwo($number)
{
$powers =[];
$power =0;
while ($number > 0) {
if ($number & 1) {
$powers[] = pow(2, $power);
}
$number = $number >> 1;
$power++;
}
return $powers;
}
/**
* 获取组合方式里面多种支付方式的值
* @param string $number 组合方式相加的和
* @param string $payTypeNumber 支付方式几种
* @return array|string
*/
function getPayType($number,$payTypeNumber)
{
// 假设有五种支付方式--数组里面有X位,求出5-X的值,就是需要补全的位数,补全在数组的前面,全部补0
//如果第一位是0就没有2次方最大的那个支付方式,是1就是有
// 二进制位数验证
$twoNum = (string)decbin($number);
$binLength = strlen($twoNum);
if ($payTypeNumber < $binLength) {
throw new \Exception("参数 payTypeNumber 必须大于或等于组合值的二进制长度(当前二进制长度为 {$binLength})");
}
$twoNum = array_reverse(str_split($twoNum));
$x = $payTypeNumber - count($twoNum);
$totalArray = array_merge(array_fill(0, $x, 0), $twoNum);
$payArray = [];
for ($i = 0; $i < count($totalArray); $i++) {
if ($totalArray[$i] == 1) {
// 写成2的多少次方
$payArray[] = pow(2, $payTypeNumber - $i-1);
}
}
return $payArray;
}
2.5 查现金+信用卡支付
->whereRaw(‘pay_type & 3 = 3’) // 3 = 1 + 2
