本文目录导读:

PHP 本身并没有内置直接使用 Luhn 算法验证信用卡号码的函数,PHP 中完全可以实现 Luhn 算法,而且实现起来非常简单。
如果需要验证信用卡号码(如判断是否为合法的卡号格式),通常的做法是:
- 自己编写一个函数来实现 Luhn 算法。
- 或者使用第三方的支付库(如
stripe-php或braintree-php),这些库内部已经包含了 Luhn 校验。
以下是一个标准的、可直接使用的 PHP 函数,用来验证信用卡号码是否通过 Luhn 算法:
PHP 实现的 Luhn 算法函数
<?php
/**
* 验证信用卡号是否通过 Luhn 算法(模10算法)
*
* @param string $number 需要验证的卡号(可以是数字字符串,包含空格或短横线会被自动清理)
* @return bool 如果通过验证返回 true,否则返回 false
*/
function isValidCreditCardLuhn($number) {
// 1. 清理输入:只保留数字
$number = preg_replace('/\D/', '', $number);
// 2. 基本长度检查(大多数信用卡号在13-19位之间)
$length = strlen($number);
if ($length < 13 || $length > 19) {
return false;
}
// 3. 执行 Luhn 算法
$sum = 0;
$alt = false; // 是否加倍(隔位加倍)
// 从右向左遍历每一位数字
for ($i = $length - 1; $i >= 0; $i--) {
$digit = intval($number[$i]);
if ($alt) {
// 如果是需要加倍的位置
$digit *= 2;
if ($digit > 9) {
// 如果加倍后大于9,则减去9(等同于将十位和个位相加)
$digit -= 9;
}
}
$sum += $digit;
$alt = !$alt; // 交替标志
}
// 4. 如果总和能被10整除,则验证通过
return ($sum % 10 === 0);
}
// --- 使用示例 ---
$testNumber = '4111 1111 1111 1111'; // 常见的 VISA 测试卡号
if (isValidCreditCardLuhn($testNumber)) {
echo "卡号 {$testNumber} 通过了 Luhn 验证(格式正确)\n";
} else {
echo "卡号 {$testNumber} 未通过 Luhn 验证(格式错误)\n";
}
$badNumber = '1234 5678 9012 3456';
echo isValidCreditCardLuhn($badNumber) ? '通过' : '不通过'; // 输出:不通过
?>
重要说明
-
Luhn 只是第一步:
- Luhn 算法只能检测 输入错误(如错位一位数字、单数字错误),可以防止完全随意的数字。
- 它不能验证:
- 该卡号是否真实发行(需要查发卡行数据库)。
- 该卡是否有余额或可用额度。
- 该卡是否过期。
- 该卡是否为伪造卡(攻击者可以生成符合 Luhn 的假卡号)。
-
更完整的验证场景: 在实际项目中,通常会结合使用:
- Luhn 算法(前端或后端快速检查格式)。
- 卡BIN(银行标识代码)验证:根据卡号前6位判断信用卡类型(Visa, MasterCard等)。
- 过期日期验证:检查年月是否已过。
- CVV验证:检查卡片背后的3位或4位安全码。
- 实际授权扣款:通过支付网关向发卡行发送一笔小额授权(通常是$0或$1),这是最可靠的验证方式。
-
常见框架/库中的内置实现(如果不想自己写):
- Laravel:可以使用
Validator::extend('card_number', ...)或安装laravel-credit-card-validation包。 - Symfony:
symfony/validator组件有CardScheme验证器。 - 通用PHP库:
respect/validation库中有CreditCard验证规则,它内部实现了 Luhn。
- Laravel:可以使用
PHP 本身不直接提供 checkLuhn() 函数,但你可以轻松实现上面的 isValidCreditCardLuhn() 函数来完成验证,这个函数是后端校验信用卡号码格式正确性的标准做法之一。