本文目录导读:

在 PHP 中实现税务计算,通常需要根据业务需求(是中国税务还是国际税务,是工资薪金还是劳务报酬)来定制算法。
由于您是中文提问,下面我以中国个人所得税(工资薪金所得) 为例,提供常见的几种计算方法和完整代码示例。
核心概念:累计预扣法
自2019年起,中国个税采用累计预扣法,这意味着不能只看单月工资,而是要计算年初到当前月的累计收入,再减去累计扣除项,算出累计应纳税额,最后减去前期已预扣的税额。
计算公式: [ \text{本月应预扣预缴税额} = (\text{累计收入}——\text{累计免税收入}——\text{累计减除费用}——\text{累计专项扣除}——\text{累计专项附加扣除}——\text{累计其他扣除}) \times \text{预扣率}——\text{速算扣除数}——\text{累计已预扣预缴税额} ]
功能封装函数(推荐)
这是一个通用的计算函数,适合月薪制和一次性计算全年或单月税费。
<?php
/**
* 中国个税(综合所得)累计预扣法计算器
*
* @param array $monthlyData 数组格式:[['salary'=>10000, 'social_security'=>500, 'special_deduction'=>2000], ...]
* (依次对应 1月, 2月... )
* salary: 应发工资, social_security: 三险一金个人部分, special_deduction: 专项附加扣除
* @return array 返回每月的应纳税额和税后工资
*/
function calculateChinaTax(array $monthlyData) {
// 基础配置(2024年标准)
$MINIMUM_DEDUCTION = 5000; // 每月基本减除费用
$results = [];
$cumulative_income = 0; // 累计收入(应发工资)
$cumulative_deduction = 0; // 累计减除费用
$cumulative_social = 0; // 累计三险一金
$cumulative_special = 0; // 累计专项附加扣除
$cumulative_tax_paid = 0; // 累计已缴税
foreach ($monthlyData as $month => $data) {
$salary = $data['salary'] ?? 0;
$social = $data['social_security'] ?? 0;
$special = $data['special_deduction'] ?? 0;
// 更新累计值
$cumulative_income += $salary;
$cumulative_deduction += $MINIMUM_DEDUCTION;
$cumulative_social += $social;
$cumulative_special += $special;
// 累计应纳税所得额 = 收入 - 扣除项
$taxable_income = $cumulative_income
- $cumulative_deduction
- $cumulative_social
- $cumulative_special;
$taxable_income = max(0, $taxable_income); // 负数按0计算
// 根据累计应纳税所得额查找税率和速算扣除数
[$rate, $quick_deduction] = getTaxRate($taxable_income);
// 累计应纳税额
$accumulated_tax = $taxable_income * $rate - $quick_deduction;
// 本月应预扣税额 = 累计应纳税额 - 累计已缴税
$monthly_tax = $accumulated_tax - $cumulative_tax_paid;
$monthly_tax = max(0, $monthly_tax); // 不能为负数
// 更新累计已缴税
$cumulative_tax_paid += $monthly_tax;
// 计算税后工资(到手工资)
$net_salary = $salary - $social - $monthly_tax;
$results[] = [
'month' => $month + 1,
'gross_salary' => $salary,
'social_security' => $social,
'special_deduction' => $special,
'taxable_income' => $taxable_income,
'monthly_tax' => $monthly_tax,
'net_salary' => $net_salary,
];
}
return $results;
}
/**
* 根据应纳税所得额获取税率和速算扣除数
* @param float $income 应纳税所得额
* @return array [税率, 速算扣除数]
*/
function getTaxRate(float $income): array {
// 中国个税综合所得税率表(年度)
$brackets = [
[0, 36000, 0.03, 0],
[36000, 144000, 0.10, 2520],
[144000, 300000, 0.20, 16920],
[300000, 420000, 0.25, 31920],
[420000, 660000, 0.30, 52920],
[660000, 960000, 0.35, 85920],
[960000, PHP_FLOAT_MAX, 0.45, 181920],
];
foreach ($brackets as $bracket) {
if ($income > $bracket[0] && $income <= $bracket[1]) {
return [$bracket[2], $bracket[3]];
}
}
// 兜底(最高档)
return [0.45, 181920];
}
// ------------------ 使用示例 ------------------
// 模拟小张1-3月工资数据
$monthlyData = [
['salary' => 15000, 'social_security' => 1500, 'special_deduction' => 2000], // 1月
['salary' => 16000, 'social_security' => 1600, 'special_deduction' => 2000], // 2月
['salary' => 15000, 'social_security' => 1500, 'special_deduction' => 2000], // 3月
];
$results = calculateChinaTax($monthlyData);
foreach ($results as $result) {
echo "月份: {$result['month']}\n";
echo "应发工资: {$result['gross_salary']}\n";
echo "社保扣除: {$result['social_security']}\n";
echo "专项附加: {$result['special_deduction']}\n";
echo "应纳税所得额: {$result['taxable_income']}\n";
echo "应缴个税: {$result['monthly_tax']}\n";
echo "税后到手: {$result['net_salary']}\n";
echo "----------------------\n";
}
?>
简单月度计算(非累计)
如果只是需要一个简单的单月速算,不考虑累计预扣(比如年终奖或外籍人员非居民个税),可以使用下面的简化逻辑:
<?php
function calculateSimpleTax($monthly_salary, $social_security = 0, $special_deduction = 0) {
// 扣除项
$deduction = 5000 + $social_security + $special_deduction;
// 应纳税所得额
$taxable_income = max(0, $monthly_salary - $deduction);
// 月度税率表
$brackets = [
[0, 3000, 0.03, 0],
[3000, 12000, 0.10, 210],
[12000, 25000, 0.20, 1410],
[25000, 35000, 0.25, 2660],
[35000, 55000, 0.30, 4410],
[55000, 80000, 0.35, 7160],
[80000, PHP_FLOAT_MAX, 0.45, 15160],
];
$tax = 0;
foreach ($brackets as $b) {
if ($taxable_income > $b[0] && $taxable_income <= $b[1]) {
$tax = $taxable_income * $b[2] - $b[3];
break;
}
}
return [
'tax' => max(0, round($tax, 2)),
'net' => round($monthly_salary - $social_security - max(0, $tax), 2),
];
}
// 测试
$result = calculateSimpleTax(15000, 1500, 2000);
echo "单月个税: " . $result['tax'] . " 元\n";
echo "税后工资: " . $result['net'] . " 元\n";
?>
关键注意事项
- 税额精度:建议使用
round($tax, 2)保留两位小数,避免类似1+0.2的浮点数问题。 - 专项附加扣除:包括赡养老人、子女教育、住房租金等,需要根据实际用户录入来动态传入参数。
- 年终奖政策:年终奖通常有单独的税率表(或者并入综合所得),根据政策选择税率,这里未展开。
- 数据库存储:在实际项目中,建议将员工的每月工资、累计数据存入数据库,方便跨月份计算。
- 其他税种:如果是针对企业,还有增值税、企业所得税,算法完全不同,需要引入财务税率表。
如果需要针对劳务报酬(按次/按月)或稿酬所得的计算,或者需要对接跨境电商增值税,请告诉我具体的业务场景。