PHP项目数据脱敏与掩码完整方案
数据脱敏核心类
<?php
namespace App\Utils;
class DataMasker
{
// 脱敏规则配置
private static $rules = [
'phone' => [
'pattern' => '/^(\d{3})\d{4}(\d{4})$/',
'replacement' => '$1****$2'
],
'email' => [
'pattern' => '/^(\w{3})\w*@(\w+\.\w+)$/',
'replacement' => '$1***@$2'
],
'id_card' => [
'pattern' => '/^(\d{6})\d{8}(\d{4})$/',
'replacement' => '$1********$2'
],
'bank_card' => [
'pattern' => '/^(\d{4})\d{8,12}(\d{4})$/',
'replacement' => '$1**** ****$2'
],
'name' => [
'pattern' => '/^(.)(.*)$/u',
'replacement' => '$1**'
],
'address' => [
'pattern' => '/^(.{6})(.*)$/u',
'replacement' => '$1****'
],
'password' => [
'pattern' => '/^.*$/',
'replacement' => '******'
]
];
/**
* 通用脱敏方法
* @param string $value 原始值
* @param string $type 数据类型
* @param array $customRule 自定义规则
* @return string
*/
public static function mask($value, $type = 'phone', $customRule = [])
{
if (empty($value)) {
return $value;
}
$rule = !empty($customRule) ? $customRule : (self::$rules[$type] ?? null);
if (!$rule) {
return $value;
}
return preg_replace($rule['pattern'], $rule['replacement'], $value);
}
/**
* 批量脱敏
* @param array $data 数据数组
* @param array $fieldRules 字段规则 ['field_name' => 'type']
* @return array
*/
public static function batchMask(array $data, array $fieldRules)
{
foreach ($data as $key => &$value) {
if (is_array($value)) {
$value = self::batchMask($value, $fieldRules);
} elseif (isset($fieldRules[$key])) {
$value = self::mask($value, $fieldRules[$key]);
}
}
return $data;
}
/**
* 自定义脱敏规则
* @param string $name 规则名称
* @param string $pattern 正则模式
* @param string $replacement 替换格式
*/
public static function addRule($name, $pattern, $replacement)
{
self::$rules[$name] = [
'pattern' => $pattern,
'replacement' => $replacement
];
}
}
数据脱敏注解实现(高级用法)
<?php
namespace App\Annotations;
/**
* @Annotation
* @Target({"PROPERTY"})
*/
class DataMask
{
public $type = 'phone'; // 脱敏类型
public $condition = null; // 脱敏条件
}
// 使用示例
class User
{
/** @DataMask(type="phone") */
public $phone;
/** @DataMask(type="email") */
public $email;
/** @DataMask(type="name") */
public $name;
}
// 注解处理器
class DataMaskProcessor
{
public static function process($object)
{
$reflection = new \ReflectionClass($object);
$properties = $reflection->getProperties();
foreach ($properties as $property) {
$annotations = self::getAnnotations($property);
if (isset($annotations['DataMask'])) {
$type = $annotations['DataMask']['type'];
$property->setAccessible(true);
$value = $property->getValue($object);
$maskedValue = DataMasker::mask($value, $type);
$property->setValue($object, $maskedValue);
}
}
return $object;
}
private static function getAnnotations(\ReflectionProperty $property)
{
$docBlock = $property->getDocComment();
preg_match_all('/@(\w+)\(([^)]*)\)/', $docBlock, $matches);
$annotations = [];
foreach ($matches[1] as $index => $name) {
$params = $matches[2][$index];
parse_str(str_replace(['"', "'", '='], ['', '', ':'], $params), $parsed);
$annotations[$name] = $parsed;
}
return $annotations;
}
}
中间件实现(请求/响应脱敏)
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class DataMaskingMiddleware
{
private $maskRules = [
'phone' => ['pattern' => '/1[3-9]\d{9}/', 'type' => 'phone'],
'email' => ['pattern' => '/\w+@\w+\.\w+/', 'type' => 'email'],
'id_card' => ['pattern' => '/\d{17}[\dXx]/', 'type' => 'id_card']
];
public function handle(Request $request, Closure $next)
{
$response = $next($request);
// 响应脱敏
if ($response->headers->get('content-type') === 'application/json') {
$content = $response->getContent();
$data = json_decode($content, true);
if (is_array($data)) {
$maskedData = $this->maskResponseData($data);
$response->setContent(json_encode($maskedData));
}
}
return $response;
}
private function maskResponseData($data)
{
if (is_array($data)) {
foreach ($data as $key => $value) {
if (is_array($value)) {
$data[$key] = $this->maskResponseData($value);
} elseif (is_string($value)) {
$data[$key] = $this->maskSensitiveData($value);
}
}
}
return $data;
}
private function maskSensitiveData($value)
{
foreach ($this->maskRules as $rule) {
if (preg_match($rule['pattern'], $value)) {
return DataMasker::mask($value, $rule['type']);
}
}
return $value;
}
}
数据库查询脱敏
<?php
namespace App\Models\Traits;
trait DataMaskingTrait
{
protected $maskable = [];
public function toArray()
{
$data = parent::toArray();
foreach ($this->maskable as $field => $type) {
if (isset($data[$field])) {
$data[$field] = DataMasker::mask($data[$field], $type);
}
}
return $data;
}
}
// 使用示例
class User extends Model
{
use DataMaskingTrait;
protected $maskable = [
'phone' => 'phone',
'email' => 'email',
'name' => 'name',
'id_card' => 'id_card'
];
}
日志脱敏处理器
<?php
namespace App\Logging;
use Monolog\Handler\AbstractProcessingHandler;
class MaskedLogHandler extends AbstractProcessingHandler
{
private $sensitiveKeys = [
'password', 'token', 'secret', 'credit_card',
'phone', 'email', 'id_card'
];
protected function write(array $record): void
{
$record['formatted'] = $this->maskSensitiveData($record['formatted']);
// 写入日志
}
private function maskSensitiveData($data)
{
if (is_array($data)) {
foreach ($data as $key => $value) {
if (in_array($key, $this->sensitiveKeys)) {
$data[$key] = '***MASKED***';
} elseif (is_array($value)) {
$data[$key] = $this->maskSensitiveData($value);
}
}
}
return $data;
}
}
使用示例
// 基本使用
$phone = DataMasker::mask('13812345678', 'phone'); // 138****5678
$email = DataMasker::mask('username@example.com', 'email'); // use***@example.com
// 批量脱敏
$userData = [
'name' => '张三',
'phone' => '13812345678',
'email' => 'user@example.com'
];
$masked = DataMasker::batchMask($userData, [
'name' => 'name',
'phone' => 'phone',
'email' => 'email'
]);
// 自定义规则
DataMasker::addRule(
'custom_phone',
'/^(\d{2})\d{7}(\d{2})$/',
'$1*****$2'
);
echo DataMasker::mask('02112345678', 'custom_phone');
最佳实践建议
- 分级脱敏:根据不同权限级别展示不同脱敏程度
- 动态配置:将脱敏规则存储在数据库或配置文件中
- 性能优化:对频繁查询的字段建立缓存
- 安全考虑:在ORM层面实现脱敏,避免遗漏
- 测试覆盖:为每种脱敏类型编写单元测试
这个方案提供了完整的PHP数据脱敏实现,涵盖了常见的数据类型和多种使用场景。

版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播