Skip to content

Commit b729080

Browse files
committed
Helpers
1 parent b62e915 commit b729080

3 files changed

Lines changed: 313 additions & 0 deletions

File tree

app/Helpers/DsnParserHelper.php

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Helpers;
6+
7+
class DsnParserHelper
8+
{
9+
public static function parse(string $dsn): array
10+
{
11+
$result = [
12+
'host' => null,
13+
'port' => 3306,
14+
'database' => null,
15+
'user' => null,
16+
'password' => null,
17+
'charset' => 'utf8mb4',
18+
'group' => null,
19+
];
20+
21+
// 解析 DSN 格式: mysql:host=xxx;port=3306;dbname=xxx;sqlLogProxyGroup=xxx
22+
$parts = explode(';', $dsn);
23+
24+
foreach ($parts as $part) {
25+
$keyValue = explode('=', $part, 2);
26+
if (count($keyValue) !== 2) {
27+
continue;
28+
}
29+
30+
$key = strtolower(trim($keyValue[0]));
31+
$value = trim($keyValue[1]);
32+
33+
switch ($key) {
34+
case 'host':
35+
case 'hostname':
36+
$result['host'] = $value;
37+
break;
38+
39+
case 'port':
40+
$result['port'] = (int) $value;
41+
break;
42+
43+
case 'dbname':
44+
case 'database':
45+
$result['database'] = $value;
46+
break;
47+
48+
case 'user':
49+
case 'username':
50+
$result['user'] = $value;
51+
break;
52+
53+
case 'password':
54+
case 'pass':
55+
$result['password'] = $value;
56+
break;
57+
58+
case 'charset':
59+
$result['charset'] = $value;
60+
break;
61+
62+
case 'sqllogproxygroup':
63+
case 'group':
64+
$result['group'] = $value;
65+
break;
66+
}
67+
}
68+
69+
return $result;
70+
}
71+
72+
public static function getGroup(string $dsn): ?string
73+
{
74+
$parsed = self::parse($dsn);
75+
return $parsed['group'];
76+
}
77+
78+
public static function getHost(string $dsn): ?string
79+
{
80+
$parsed = self::parse($dsn);
81+
return $parsed['host'];
82+
}
83+
84+
public static function getPort(string $dsn): int
85+
{
86+
$parsed = self::parse($dsn);
87+
return $parsed['port'];
88+
}
89+
90+
public static function getDatabase(string $dsn): ?string
91+
{
92+
$parsed = self::parse($dsn);
93+
return $parsed['database'];
94+
}
95+
96+
public static function extractParams(string $dsn, array $paramKeys): array
97+
{
98+
$parsed = self::parse($dsn);
99+
$result = [];
100+
101+
foreach ($paramKeys as $key) {
102+
$lowerKey = strtolower($key);
103+
if (isset($parsed[$lowerKey])) {
104+
$result[$key] = $parsed[$lowerKey];
105+
}
106+
}
107+
108+
return $result;
109+
}
110+
}

app/Helpers/SqlHelper.php

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Helpers;
6+
7+
class SqlHelper
8+
{
9+
private static array $keywords = [
10+
'SELECT', 'FROM', 'WHERE', 'INSERT', 'INTO', 'VALUES',
11+
'UPDATE', 'SET', 'DELETE', 'CREATE', 'DROP', 'ALTER',
12+
'TABLE', 'INDEX', 'JOIN', 'LEFT', 'RIGHT', 'INNER', 'OUTER',
13+
'ON', 'AND', 'OR', 'NOT', 'NULL', 'IS', 'LIKE', 'IN',
14+
'BETWEEN', 'ORDER BY', 'GROUP BY', 'HAVING', 'LIMIT', 'OFFSET',
15+
'UNION', 'DISTINCT', 'AS', 'BY', 'DESC', 'ASC', 'WITH',
16+
'REPLACE', 'TRUNCATE', 'SHOW', 'DESCRIBE', 'EXPLAIN',
17+
'BEGIN', 'COMMIT', 'ROLLBACK', 'START TRANSACTION',
18+
];
19+
20+
/**
21+
* SQL语法高亮
22+
*/
23+
public static function highlightSql(string $sql): string
24+
{
25+
$highlighted = $sql;
26+
27+
// 高亮关键字
28+
foreach (self::$keywords as $keyword) {
29+
$pattern = '/\b(' . $keyword . ')\b/i';
30+
$replacement = "\033[1;35m$1\033[0m"; // 紫色加粗
31+
$highlighted = preg_replace($pattern, $replacement, $highlighted);
32+
}
33+
34+
// 高亮字符串
35+
$highlighted = preg_replace(
36+
'/\'([^\']*)\'/',
37+
"\033[32m'$1'\033[0m", // 绿色
38+
$highlighted
39+
);
40+
41+
// 高亮数字
42+
$highlighted = preg_replace(
43+
'/\b(\d+)\b/',
44+
"\033[33m$1\033[0m", // 黄色
45+
$highlighted
46+
);
47+
48+
return $highlighted;
49+
}
50+
51+
/**
52+
* 格式化SQL(简单版)
53+
*/
54+
public static function formatSql(string $sql): string
55+
{
56+
$sql = Query::normalizeSql($sql);
57+
58+
// 在关键字后添加换行
59+
$keywords = ['SELECT', 'FROM', 'WHERE', 'INSERT', 'INTO', 'VALUES',
60+
'UPDATE', 'SET', 'DELETE', 'LEFT JOIN', 'RIGHT JOIN',
61+
'INNER JOIN', 'ORDER BY', 'GROUP BY', 'HAVING', 'LIMIT'];
62+
63+
foreach (array_reverse($keywords) as $keyword) {
64+
$pattern = '/\b(' . $keyword . ')\b/i';
65+
$sql = preg_replace($pattern, "\n$1", $sql);
66+
}
67+
68+
// 移除开头的换行
69+
return trim($sql);
70+
}
71+
72+
/**
73+
* 获取SQL类型
74+
*/
75+
public static function getSqlType(string $sql): string
76+
{
77+
$sql = strtoupper(trim($sql));
78+
79+
if (str_starts_with($sql, 'SELECT')) {
80+
return 'SELECT';
81+
} elseif (str_starts_with($sql, 'INSERT')) {
82+
return 'INSERT';
83+
} elseif (str_starts_with($sql, 'UPDATE')) {
84+
return 'UPDATE';
85+
} elseif (str_starts_with($sql, 'DELETE')) {
86+
return 'DELETE';
87+
} elseif (str_starts_with($sql, 'CREATE')) {
88+
return 'CREATE';
89+
} elseif (str_starts_with($sql, 'DROP')) {
90+
return 'DROP';
91+
} elseif (str_starts_with($sql, 'ALTER')) {
92+
return 'ALTER';
93+
} elseif (str_starts_with($sql, 'SHOW')) {
94+
return 'SHOW';
95+
} elseif (str_starts_with($sql, 'DESCRIBE') || str_starts_with($sql, 'DESC')) {
96+
return 'DESCRIBE';
97+
} elseif (str_starts_with($sql, 'BEGIN') || str_starts_with($sql, 'START TRANSACTION')) {
98+
return 'BEGIN';
99+
} elseif (str_starts_with($sql, 'COMMIT')) {
100+
return 'COMMIT';
101+
} elseif (str_starts_with($sql, 'ROLLBACK')) {
102+
return 'ROLLBACK';
103+
}
104+
105+
return 'OTHER';
106+
}
107+
108+
/**
109+
* 提取表名
110+
*/
111+
public static function extractTableNames(string $sql): array
112+
{
113+
$tables = [];
114+
$sql = strtoupper($sql);
115+
116+
// FROM 子句
117+
if (preg_match_all('/FROM\s+(\w+)/', $sql, $matches)) {
118+
$tables = array_merge($tables, $matches[1]);
119+
}
120+
121+
// JOIN 子句
122+
if (preg_match_all('/(?:JOIN)\s+(\w+)/', $sql, $matches)) {
123+
$tables = array_merge($tables, $matches[1]);
124+
}
125+
126+
// INSERT INTO
127+
if (preg_match('/INSERT\s+INTO\s+(\w+)/', $sql, $matches)) {
128+
$tables[] = $matches[1];
129+
}
130+
131+
// UPDATE
132+
if (preg_match('/UPDATE\s+(\w+)/', $sql, $matches)) {
133+
$tables[] = $matches[1];
134+
}
135+
136+
// DELETE FROM
137+
if (preg_match('/DELETE\s+FROM\s+(\w+)/', $sql, $matches)) {
138+
$tables[] = $matches[1];
139+
}
140+
141+
return array_unique($tables);
142+
}
143+
}

app/Helpers/WildcardHelper.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Helpers;
6+
7+
class WildcardHelper
8+
{
9+
/**
10+
* 通配符匹配
11+
* 支持 * 匹配任意字符
12+
*/
13+
public static function match(string $pattern, string $text): bool
14+
{
15+
$pattern = self::normalizePattern($pattern);
16+
17+
// 转义正则表达式特殊字符(除了*)
18+
$regex = str_replace(
19+
['\\', '^', '$', '.', '+', '?', '[', ']', '(', ')', '|', '{', '}'],
20+
['\\\\', '\\^', '\\$', '\\.', '\\+', '\\?', '\\[', '\\]', '\\(', '\\)', '\\|', '\\{', '\\}'],
21+
$pattern
22+
);
23+
24+
// 将 * 替换为 .* (匹配任意字符)
25+
$regex = str_replace('*', '.*', $regex);
26+
27+
// 添加开始和结束锚点
28+
$regex = '/^' . $regex . '$/i';
29+
30+
return preg_match($regex, $text) === 1;
31+
}
32+
33+
/**
34+
* 批量匹配
35+
* @param string[] $patterns
36+
*/
37+
public static function matchAny(array $patterns, string $text): bool
38+
{
39+
foreach ($patterns as $pattern) {
40+
if (self::match($pattern, $text)) {
41+
return true;
42+
}
43+
}
44+
return false;
45+
}
46+
47+
private static function normalizePattern(string $pattern): string
48+
{
49+
return trim($pattern);
50+
}
51+
52+
/**
53+
* 检查SQL是否匹配排除规则
54+
* @param string[] $excludePatterns
55+
*/
56+
public static function shouldExclude(string $sql, array $excludePatterns): bool
57+
{
58+
return self::matchAny($excludePatterns, $sql);
59+
}
60+
}

0 commit comments

Comments
 (0)