文章目录[隐藏]
手把手教学:为WordPress集成智能化的网站表单数据验证与清洗工具
引言:为什么WordPress网站需要智能表单验证与清洗
在当今互联网环境中,网站表单是与用户互动的重要桥梁。无论是联系表单、注册表单、订单表单还是调查问卷,表单数据的质量直接影响到用户体验、数据分析和业务决策。然而,许多WordPress网站管理员面临一个共同问题:如何确保用户提交的表单数据既准确又安全?
传统的表单验证方法往往只停留在基础层面,如检查必填字段或简单的格式验证。但随着网络攻击手段的日益复杂和用户期望的提高,我们需要更智能的解决方案。本文将手把手教您如何通过WordPress代码二次开发,集成智能化的表单数据验证与清洗工具,将常用互联网小工具功能融入您的网站。
第一章:理解WordPress表单生态系统
1.1 WordPress常用表单插件分析
WordPress生态系统中有众多表单插件,如Contact Form 7、Gravity Forms、WPForms和Ninja Forms等。这些插件提供了丰富的表单构建功能,但在数据验证和清洗方面往往存在局限性:
- 基础验证功能:大多数插件提供必填字段、电子邮件格式、数字范围等基础验证
- 有限的清洗能力:对用户输入的潜在危险内容过滤不足
- 缺乏智能验证:无法识别虚假信息、垃圾内容或恶意输入
- 扩展性有限:自定义验证规则需要复杂的配置或额外插件
1.2 表单数据面临的主要风险
在集成智能验证工具前,我们需要了解表单数据面临的主要风险:
- 安全威胁:SQL注入、跨站脚本攻击(XSS)、跨站请求伪造(CSRF)
- 数据质量问题:虚假信息、格式错误、不一致的数据
- 垃圾信息:广告内容、垃圾邮件、机器人提交
- 用户体验问题:复杂的验证流程、不清晰的错误提示
1.3 智能验证与清洗的核心概念
智能表单验证与清洗不仅仅是检查数据格式,还包括:
- 上下文感知验证:根据字段类型和业务逻辑进行验证
- 实时反馈:在用户输入时提供即时验证反馈
- 数据标准化:将不同格式的数据转换为统一格式
- 威胁检测:识别并阻止恶意内容提交
- 垃圾信息过滤:使用多种技术识别和过滤垃圾提交
第二章:搭建开发环境与准备工作
2.1 开发环境配置
在开始二次开发前,确保您已准备好以下环境:
- 本地开发环境:推荐使用Local by Flywheel、XAMPP或MAMP
- 代码编辑器:VS Code、PHPStorm或Sublime Text
- WordPress安装:最新版本的WordPress
- 调试工具:安装Query Monitor、Debug Bar等调试插件
- 版本控制:Git用于代码版本管理
2.2 创建自定义插件
为了避免主题更新导致代码丢失,我们将创建一个独立插件来实现表单验证功能:
- 在
wp-content/plugins/目录下创建新文件夹smart-form-validation - 创建主插件文件
smart-form-validation.php,添加插件头部信息:
<?php
/**
* Plugin Name: Smart Form Validation & Sanitization
* Plugin URI: https://yourwebsite.com/
* Description: 智能表单验证与清洗工具,增强WordPress表单安全性
* Version: 1.0.0
* Author: Your Name
* License: GPL v2 or later
* Text Domain: smart-form-validation
*/
2.3 安全注意事项
在进行二次开发时,请牢记以下安全准则:
- 始终对用户输入进行验证、清洗和转义
- 使用WordPress非ce和权限检查功能
- 避免直接执行用户提供的代码
- 定期更新和维护您的自定义代码
第三章:核心验证功能实现
3.1 基础验证类设计
我们将创建一个核心验证类,包含常用的验证方法:
class Smart_Form_Validator {
private $errors = array();
private $cleaned_data = array();
/**
* 验证电子邮件地址
*/
public function validate_email($email, $field_name = 'email') {
if (empty($email)) {
$this->add_error($field_name, __('电子邮件地址不能为空', 'smart-form-validation'));
return false;
}
// 使用WordPress内置函数验证邮箱格式
if (!is_email($email)) {
$this->add_error($field_name, __('请输入有效的电子邮件地址', 'smart-form-validation'));
return false;
}
// 检查邮箱域名是否真实存在
if (apply_filters('smart_form_check_email_domain', true)) {
list($user, $domain) = explode('@', $email);
if (!checkdnsrr($domain, 'MX')) {
$this->add_error($field_name, __('电子邮件域名无效', 'smart-form-validation'));
return false;
}
}
$this->cleaned_data[$field_name] = sanitize_email($email);
return true;
}
/**
* 验证电话号码
*/
public function validate_phone($phone, $field_name = 'phone', $country_code = 'CN') {
$phone = preg_replace('/s+/', '', $phone);
// 中国手机号验证
if ($country_code === 'CN') {
if (!preg_match('/^1[3-9]d{9}$/', $phone)) {
$this->add_error($field_name, __('请输入有效的中国手机号码', 'smart-form-validation'));
return false;
}
}
// 国际电话验证(简化版)
else {
if (!preg_match('/^+?[1-9]d{1,14}$/', $phone)) {
$this->add_error($field_name, __('请输入有效的国际电话号码', 'smart-form-validation'));
return false;
}
}
$this->cleaned_data[$field_name] = sanitize_text_field($phone);
return true;
}
/**
* 验证URL
*/
public function validate_url($url, $field_name = 'url') {
if (empty($url)) {
return true; // URL字段可为空
}
// 检查URL格式
if (!filter_var($url, FILTER_VALIDATE_URL)) {
$this->add_error($field_name, __('请输入有效的URL地址', 'smart-form-validation'));
return false;
}
// 检查URL是否安全
$parsed_url = parse_url($url);
$blacklist_domains = apply_filters('smart_form_url_blacklist', array());
if (in_array($parsed_url['host'], $blacklist_domains)) {
$this->add_error($field_name, __('该URL已被列入黑名单', 'smart-form-validation'));
return false;
}
$this->cleaned_data[$field_name] = esc_url_raw($url);
return true;
}
/**
* 添加错误信息
*/
private function add_error($field, $message) {
$this->errors[$field] = $message;
}
/**
* 获取所有错误
*/
public function get_errors() {
return $this->errors;
}
/**
* 获取清洗后的数据
*/
public function get_cleaned_data() {
return $this->cleaned_data;
}
/**
* 检查是否有错误
*/
public function has_errors() {
return !empty($this->errors);
}
}
3.2 高级验证功能实现
除了基础验证,我们还需要实现更智能的验证功能:
/**
* 智能文本内容验证
*/
public function validate_smart_text($text, $field_name, $options = array()) {
$defaults = array(
'min_length' => 0,
'max_length' => 0,
'allow_html' => false,
'block_spam_keywords' => true,
'check_duplicate' => false,
);
$options = wp_parse_args($options, $defaults);
// 检查长度
$text_length = mb_strlen($text, 'UTF-8');
if ($options['min_length'] > 0 && $text_length < $options['min_length']) {
$this->add_error($field_name, sprintf(__('内容至少需要%d个字符', 'smart-form-validation'), $options['min_length']));
return false;
}
if ($options['max_length'] > 0 && $text_length > $options['max_length']) {
$this->add_error($field_name, sprintf(__('内容不能超过%d个字符', 'smart-form-validation'), $options['max_length']));
return false;
}
// 垃圾关键词检测
if ($options['block_spam_keywords']) {
$spam_keywords = $this->get_spam_keywords();
foreach ($spam_keywords as $keyword) {
if (stripos($text, $keyword) !== false) {
$this->add_error($field_name, __('内容包含不被允许的关键词', 'smart-form-validation'));
return false;
}
}
}
// 重复内容检测
if ($options['check_duplicate']) {
$hash = md5($text);
$existing_hashes = get_option('smart_form_submission_hashes', array());
// 清理过期的哈希值(24小时前的提交)
$one_day_ago = time() - 86400;
foreach ($existing_hashes as $timestamp => $content_hash) {
if ($timestamp < $one_day_ago) {
unset($existing_hashes[$timestamp]);
}
}
if (in_array($hash, $existing_hashes)) {
$this->add_error($field_name, __('检测到重复提交的内容', 'smart-form-validation'));
return false;
}
// 存储当前提交的哈希值
$existing_hashes[time()] = $hash;
update_option('smart_form_submission_hashes', $existing_hashes);
}
// 数据清洗
if ($options['allow_html']) {
// 允许有限的HTML标签
$allowed_tags = wp_kses_allowed_html('post');
$cleaned_text = wp_kses($text, $allowed_tags);
} else {
// 完全清除HTML
$cleaned_text = sanitize_textarea_field($text);
}
$this->cleaned_data[$field_name] = $cleaned_text;
return true;
}
/**
* 获取垃圾关键词列表
*/
private function get_spam_keywords() {
$default_keywords = array(
'viagra', 'cialis', 'casino', 'loan', 'mortgage',
'赚钱', '赌博', '色情', '代开发票', '信用卡套现'
);
return apply_filters('smart_form_spam_keywords', $default_keywords);
}
3.3 实时AJAX验证
为了提高用户体验,我们可以添加实时验证功能:
/**
* 注册AJAX验证端点
*/
public function register_ajax_handlers() {
add_action('wp_ajax_smart_form_validate_field', array($this, 'ajax_validate_field'));
add_action('wp_ajax_nopriv_smart_form_validate_field', array($this, 'ajax_validate_field'));
}
/**
* AJAX字段验证处理
*/
public function ajax_validate_field() {
// 安全检查
check_ajax_referer('smart_form_validation_nonce', 'nonce');
$field_name = sanitize_text_field($_POST['field_name'] ?? '');
$field_value = $_POST['field_value'] ?? '';
$field_type = sanitize_text_field($_POST['field_type'] ?? 'text');
$validator = new Smart_Form_Validator();
$is_valid = false;
$message = '';
switch ($field_type) {
case 'email':
$is_valid = $validator->validate_email($field_value, $field_name);
break;
case 'phone':
$is_valid = $validator->validate_phone($field_value, $field_name);
break;
case 'url':
$is_valid = $validator->validate_url($field_value, $field_name);
break;
default:
$is_valid = true;
}
if (!$is_valid) {
$errors = $validator->get_errors();
$message = $errors[$field_name] ?? __('字段验证失败', 'smart-form-validation');
}
wp_send_json(array(
'valid' => $is_valid,
'message' => $message,
'cleaned_value' => $validator->get_cleaned_data()[$field_name] ?? $field_value
));
}
第四章:数据清洗与安全防护
4.1 深度数据清洗
数据清洗不仅仅是去除危险字符,还包括标准化和规范化:
/**
* 深度数据清洗类
*/
class Smart_Data_Sanitizer {
/**
* 清洗用户输入数组
*/
public static function sanitize_array($data, $rules = array()) {
$sanitized = array();
foreach ($data as $key => $value) {
$rule = $rules[$key] ?? 'text';
if (is_array($value)) {
$sanitized[$key] = self::sanitize_array($value, $rules);
} else {
$sanitized[$key] = self::sanitize_field($value, $rule);
}
}
return $sanitized;
}
/**
* 根据规则清洗单个字段
*/
public static function sanitize_field($value, $rule = 'text') {
switch ($rule) {
case 'email':
return sanitize_email($value);
case 'url':
return esc_url_raw($value);
case 'textarea':
return sanitize_textarea_field($value);
case 'html':
$allowed_tags = wp_kses_allowed_html('post');
return wp_kses($value, $allowed_tags);
case 'integer':
return intval($value);
case 'float':
return floatval($value);
case 'date':
// 尝试解析日期并格式化为Y-m-d
$timestamp = strtotime($value);
return $timestamp ? date('Y-m-d', $timestamp) : '';
case 'phone':
// 移除所有非数字字符,除了开头的+
$cleaned = preg_replace('/[^d+]/', '', $value);
return substr($cleaned, 0, 20); // 限制长度
case 'credit_card':
// 只保留数字,并添加掩码
$cleaned = preg_replace('/D/', '', $value);
if (strlen($cleaned) >= 4) {
return '**** **** **** ' . substr($cleaned, -4);
}
return $cleaned;
case 'price':
// 格式化价格,保留两位小数
$cleaned = preg_replace('/[^d.]/', '', $value);
$float_value = floatval($cleaned);
return number_format($float_value, 2, '.', '');
default:
return sanitize_text_field($value);
}
}
/**
* 防止SQL注入
*/
public static function prevent_sql_injection($input) {
global $wpdb;
// 使用$wpdb->prepare进行查询参数化
// 这里我们主要进行输入验证
$dangerous_patterns = array(
'/unions+select/i',
'/inserts+into/i',
'/updates+.+set/i',
'/deletes+from/i',
'/drops+table/i',
'/--/',
'/#/',
'//*/',
'/*//',
'/waitfors+delay/i',
'/benchmark(/i'
);
foreach ($dangerous_patterns as $pattern) {
if (preg_match($pattern, $input)) {
return ''; // 发现危险内容,返回空字符串
}
}
return $input;
}
/**
* 防止XSS攻击
*/
public static function prevent_xss($input) {
// 移除危险的HTML属性和事件处理器
$dangerous_attributes = array(
'onload', 'onerror', 'onclick', 'onmouseover',
'onmouseout', 'onkeydown', 'onkeypress', 'onkeyup',
'javascript:', 'vbscript:', 'expression('
);
foreach ($dangerous_attributes as $attr) {
$input = preg_replace('/' . preg_quote($attr, '/') . 's*:/i', 'blocked:', $input);
$input = preg_replace('/' . preg_quote($attr, '/') . 's*=/i', 'blocked=', $input);
}
return $input;
}
}
4.2 垃圾信息检测与防护
/**
* 垃圾信息检测类
*/
class Smart_Spam_Detector {
private $score = 0;
private $threshold = 5; // 超过此分数视为垃圾信息
/**
* 检测提交是否为垃圾信息
*/
public function is_spam($data) {
$this->score = 0;
// 检查提交频率
$this->check_submission_frequency();
// 检查隐藏蜜罐字段
$this->check_honeypot($data);
// 检查内容特征
if (isset($data['message'])) {
$this->check_content_features($data['message']);
}
// 检查链接数量
$this->check_link_count($data);
// 检查用户代理
$this->check_user_agent();
// 允许其他插件修改分数
$this->score = apply_filters('smart_form_spam_score', $this->score, $data);
return $this->score >= $this->threshold;
}
/**
* 检查提交频率
*/
private function check_submission_frequency() {
$ip = $this->get_user_ip();
$transient_key = 'smart_form_submission_' . md5($ip);
$submission_count = get_transient($transient_key);
if ($submission_count === false) {
$submission_count = 0;
set_transient($transient_key, 1, 300); // 5分钟限制
} else {
$submission_count++;
set_transient($transient_key, $submission_count, 300);
// 短时间内多次提交增加垃圾分数
if ($submission_count > 3) {
$this->score += ($submission_count - 2) * 2;
}
}
}
/**
* 检查蜜罐字段
*/
private function check_honeypot($data) {
// 蜜罐字段名,对用户不可见
$honeypot_field = apply_filters('smart_form_honeypot_field', 'website_url');
if (isset($data[$honeypot_field]) && !empty($data[$honeypot_field])) {
// 蜜罐字段被填写,很可能是机器人
$this->score += 10;
}
}
/**
* 检查内容特征
*/
private function check_content_features($content) {
// 检查大写字母比例
$total_chars = strlen($content);
$uppercase_chars = preg_match_all('/[A-Z]/', $content);
if ($total_chars > 10) {
$uppercase_ratio = $uppercase_chars / $total_chars;
if ($uppercase_ratio > 0.5) {
$this->score += 3; // 过多大写字母
}
}
// 检查垃圾关键词
$spam_keywords = array(
'viagra', 'cialis', 'casino', 'loan', 'mortgage',
'赚钱', '赌博', '色情', '代开发票', '信用卡套现'
);
foreach ($spam_keywords as $keyword) {
if (stripos($content, $keyword) !== false) {
$this->score += 5;
break;
}
}
// 检查无意义重复
if ($this->has_repetitive_pattern($content)) {
$this->score += 4;
}
}
/**
* 检查链接数量
*/
private function check_link_count($data) {
$total_links = 0;
foreach ($data as $value) {
if (is_string($value)) {
// 简单统计链接数量
$links = preg_match_all('/https?://[^s]+/', $value, $matches);
$total_links += $links;
}
}
if ($total_links > 2) {
$this->score += $total_links; // 每个链接加1分
}
}
/**
* 检查用户代理
*/
private function check_user_agent() {
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
if (empty($user_agent)) {
$this->score += 3; // 空用户代理
return;
}
// 已知的垃圾机器人用户代理
$spam_bots = array(
'bot', 'crawler', 'spider', 'scraper',
'curl', 'wget', 'python-requests', 'java'
);
foreach ($spam_bots as $bot) {
if (stripos($user_agent, $bot) !== false) {
$this->score += 2;
break;
}
}
}
/**
* 获取用户IP
*/
private function get_user_ip() {
$ip = '';
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
}
return sanitize_text_field($ip);
}
/**
* 检查是否有重复模式
*/
private function has_repetitive_pattern($content) {
// 检查连续重复的单词
if (preg_match('/(bw+b)(?:s+1){2,}/i', $content)) {
return true;
}
// 检查重复字符
if (preg_match('/(.)1{5,}/', $content)) {
return true;
}
return false;
}
}
第五章:集成常用互联网小工具功能
5.1 地址智能补全与验证
/**
* 地址智能处理类
*/
class Smart_Address_Processor {
/**
* 集成第三方地址API进行验证
*/
public static function validate_address($address, $country = 'CN') {
$result = array(
'valid' => false,
'normalized' => '',
'components' => array(),
'suggestions' => array()
);
// 基础格式验证
if (empty($address) || strlen($address) < 5) {
return $result;
}
// 使用百度地图API进行地址验证(示例)
if ($country === 'CN' && defined('SMART_FORM_BAIDU_MAP_AK')) {
$api_result = self::validate_via_baidu_map($address);
if ($api_result) {
return $api_result;
}
}
// 本地规则验证
return self::validate_locally($address, $country);
}
/**
* 通过百度地图API验证地址
*/
private static function validate_via_baidu_map($address) {
$api_key = SMART_FORM_BAIDU_MAP_AK;
$url = "http://api.map.baidu.com/geocoding/v3/?address=" .
urlencode($address) . "&output=json&ak=" . $api_key;
$response = wp_remote_get($url, array('timeout' => 5));
if (is_wp_error($response)) {
return false;
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if ($data && $data['status'] == 0) {
return array(
'valid' => true,
'normalized' => $data['result']['formatted_address'] ?? $address,
'components' => array(
'province' => $data['result']['addressComponent']['province'] ?? '',
'city' => $data['result']['addressComponent']['city'] ?? '',
'district' => $data['result']['addressComponent']['district'] ?? '',
'street' => $data['result']['addressComponent']['street'] ?? ''
),
'location' => array(
'lng' => $data['result']['location']['lng'] ?? '',
'lat' => $data['result']['location']['lat'] ?? ''
)
);
}
return false;
}
/**
* 本地地址验证规则
*/
private static function validate_locally($address, $country) {
$result = array(
'valid' => false,
'normalized' => $address,
'components' => array()
);
// 中国地址验证规则
if ($country === 'CN') {
// 检查是否包含必要的地址元素
$required_elements = array('省', '市', '区', '路', '街', '号');
$found_elements = 0;
foreach ($required_elements as $element) {
if (mb_strpos($address, $element) !== false) {
$found_elements++;
}
}
$result['valid'] = $found_elements >= 2;
// 尝试提取地址组件
if (preg_match('/(.*?[省市])(.*?[市区县])(.*?[路街道])(.*)/', $address, $matches)) {
$result['components'] = array(
'province' => $matches[1] ?? '',
'city' => $matches[2] ?? '',
'district' => $matches[3] ?? '',
'detail' => $matches[4] ?? ''
);
}
}
return $result;
}
/**
* 地址自动补全
*/
public static function autocomplete_address($input, $country = 'CN') {
$suggestions = array();
// 这里可以集成第三方地址补全API
// 示例:使用本地地址数据库
$address_database = get_option('smart_form_address_db', array());
if (!empty($address_database)) {
foreach ($address_database as $address) {
if (stripos($address, $input) !== false) {
$suggestions[] = $address;
if (count($suggestions) >= 5) {
break;
}
}
}
}
return apply_filters('smart_form_address_suggestions', $suggestions, $input, $country);
}
}
5.2 身份证号码验证工具
/**
* 身份证验证类
*/
class Smart_ID_Validator {
/**
* 验证中国身份证号码
*/
public static function validate_chinese_id($id_number) {
$id_number = strtoupper(trim($id_number));
// 基本格式验证
if (!preg_match('/^d{17}[dX]$/', $id_number)) {
return array(
'valid' => false,
'error' => '身份证格式不正确',
'details' => array()
);
}
// 验证校验码
if (!self::verify_check_code($id_number)) {
return array(
'valid' => false,
'error' => '身份证校验码错误',
'details' => array()
);
}
// 提取信息
$details = self::extract_id_info($id_number);
// 验证出生日期
if (!checkdate($details['month'], $details['day'], $details['year'])) {
return array(
'valid' => false,
'error' => '身份证出生日期无效',
'details' => $details
);
}
// 验证地区代码(前6位)
if (!self::validate_region_code(substr($id_number, 0, 6))) {
return array(
'valid' => false,
'error' => '身份证地区代码无效',
'details' => $details
);
}
return array(
'valid' => true,
'error' => '',
'details' => $details
);
}
/**
* 验证校验码
*/
private static function verify_check_code($id_number) {
if (strlen($id_number) != 18) {
return false;
}
// 加权因子
$weight_factors = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
// 校验码对应值
$check_codes = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
$sum = 0;
for ($i = 0; $i < 17; $i++) {
$sum += intval($id_number[$i]) * $weight_factors[$i];
}
$mod = $sum % 11;
$check_code = $check_codes[$mod];
return $check_code == $id_number[17];
}
/**
* 从身份证提取信息
*/
private static function extract_id_info($id_number) {
// 地区代码
$region_code = substr($id_number, 0, 6);
// 出生日期
$birth_year = substr($id_number, 6, 4);
$birth_month = substr($id_number, 10, 2);
$birth_day = substr($id_number, 12, 2);
// 顺序码
$sequence_code = substr($id_number, 14, 3);
// 性别(顺序码奇数为男,偶数为女)
$gender_code = intval($sequence_code);
$gender = ($gender_code % 2 == 1) ? '男' : '女';
// 年龄计算
$current_year = date('Y');
$age = $current_year - $birth_year;
// 判断是否已过生日
$current_month = date('m');
$current_day = date('d');
if ($current_month < $birth_month ||
($current_month == $birth_month && $current_day < $birth_day)) {
$age--;
}
return array(
'region_code' => $region_code,
'birth_date' => $birth_year . '-' . $birth_month . '-' . $birth_day,
'year' => intval($birth_year),
'month' => intval($birth_month),
'day' => intval($birth_day),
'sequence_code' => $sequence_code,
'gender' => $gender,
'age' => $age
);
}
/**
* 验证地区代码
*/
private static function validate_region_code($region_code) {
// 这里可以集成地区代码数据库
// 简化版:只验证基本格式
$valid_prefixes = array(
'11', '12', '13', '14', '15', // 华北
'21', '22', '23', // 东北
'31', '32', '33', '34', // 华东
'35', '36', '37', // 华中
'41', '42', '43', '44', '45', '46', // 华南
'50', '51', '52', '53', '54', // 西南
'61', '62', '63', '64', '65', // 西北
'71', '81', '82' // 港澳台
);
$prefix = substr($region_code, 0, 2);
return in_array($prefix, $valid_prefixes);
}
}
5.3 银行卡号验证与识别
/**
* 银行卡验证类
*/
class Smart_Bankcard_Validator {
/**
* 验证银行卡号
*/
public static function validate_bankcard($card_number) {
$card_number = preg_replace('/s+/', '', $card_number);
// 基本格式验证
if (!preg_match('/^d{13,19}$/', $card_number)) {
return array(
'valid' => false,
'error' => '银行卡号格式不正确',
'details' => array()
);
}
// Luhn算法验证
if (!self::validate_luhn($card_number)) {
return array(
'valid' => false,
'error' => '银行卡号校验失败',
'details' => array()
);
}
// 识别银行和卡类型
$details = self::identify_bankcard($card_number);
return array(
'valid' => true,
'error' => '',
'details' => $details
);
}
/**
* Luhn算法验证
*/
private static function validate_luhn($card_number) {
$sum = 0;
$length = strlen($card_number);
$parity = $length % 2;
for ($i = 0; $i < $length; $i++) {
$digit = intval($card_number[$i]);
if ($i % 2 == $parity) {
$digit *= 2;
if ($digit > 9) {
$digit -= 9;
}
}
$sum += $digit;
}
return ($sum % 10) == 0;
}
/**
* 识别银行卡信息
*/
private static function identify_bankcard($card_number) {
$bin_codes = array(
// 借记卡
'622848' => array('bank' => '农业银行', 'type' => '借记卡'),
'622700' => array('bank' => '建设银行', 'type' => '借记卡'),
'622262' => array('bank' => '交通银行', 'type' => '借记卡'),
'622588' => array('bank' => '招商银行', 'type' => '借记卡'),
'622760' => array('bank' => '中国银行', 'type' => '借记卡'),
'622202' => array('bank' => '工商银行', 'type' => '借记卡'),
// 信用卡
'438088' => array('bank' => '建设银行', 'type' => '信用卡'),
'518710' => array('bank' => '招商银行', 'type' => '信用卡'),
'622155' => array('bank' => '工商银行', 'type' => '信用卡'),
'622156' => array('bank' => '工商银行', 'type' => '信用卡'),
// 更多BIN码可以继续添加
);
$details = array(
'bank' => '未知',
'type' => '未知',
'length' => strlen($card_number),
'bin' => substr($card_number, 0, 6)
);
// 检查前6位BIN码
foreach ($bin_codes as $bin => $info) {
