Files
Ai-Single-Page/deepseek/db-strong.php
T
2025-10-30 00:30:43 +00:00

274 lines
10 KiB
PHP

<?php
/**
* MySQL数据库连接测试脚本 - 修复密码特殊符号问题
* 使用方法:
* php mysql_test.php --host=localhost --user=root --password='your@password#' --database=test
* php mysql_test.php -h localhost -u root -p 'your@password#' -d test
*/
class MySQLConnectionTester {
private $host;
private $username;
private $password;
private $database;
private $port;
public function __construct($config = []) {
$this->host = $config['host'] ?? 'localhost';
$this->username = $config['username'] ?? 'root';
$this->password = $config['password'] ?? '';
$this->database = $config['database'] ?? 'test';
$this->port = $config['port'] ?? 3306;
}
public function testConnection() {
$this->printHeader();
// 安全地显示连接信息(隐藏密码)
$this->printConnectionInfo();
try {
// 测试连接
$result = $this->connect();
$this->printSuccess($result);
// 测试查询
$this->testQueries($result['pdo']);
} catch (Exception $e) {
$this->printError($e);
return false;
}
$this->printFooter();
return true;
}
private function connect() {
$start_time = microtime(true);
$dsn = "mysql:host={$this->host};port={$this->port};dbname={$this->database};charset=utf8mb4";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_TIMEOUT => 5, // 5秒连接超时
];
$pdo = new PDO($dsn, $this->username, $this->password, $options);
$end_time = microtime(true);
$connection_time = round(($end_time - $start_time) * 1000, 2);
return [
'pdo' => $pdo,
'connection_time' => $connection_time,
'server_version' => $pdo->getAttribute(PDO::ATTR_SERVER_VERSION),
'client_version' => $pdo->getAttribute(PDO::ATTR_CLIENT_VERSION)
];
}
private function testQueries($pdo) {
echo "执行测试查询...\n";
// 测试1: 简单查询
$stmt = $pdo->query("SELECT 1 as test_value, NOW() as current_time");
$result = $stmt->fetch();
echo "✅ 简单查询测试: 成功\n";
// 测试2: 显示当前用户和数据库
$stmt = $pdo->query("SELECT USER() as current_user, DATABASE() as current_database");
$info = $stmt->fetch();
echo "当前用户: {$info['current_user']}\n";
echo "当前数据库: {$info['current_database']}\n";
// 测试3: 显示进程列表(前5个)
try {
$stmt = $pdo->query("SHOW PROCESSLIST LIMIT 5");
$processes = $stmt->fetchAll();
echo "当前连接数: " . count($processes) . "\n";
} catch (Exception $e) {
echo "⚠️ 无法查看进程列表(权限不足)\n";
}
}
private function printHeader() {
echo "========================================\n";
echo "MySQL数据库连接测试\n";
echo "========================================\n";
}
private function printConnectionInfo() {
echo "连接信息:\n";
echo "主机: {$this->host}:{$this->port}\n";
echo "数据库: {$this->database}\n";
echo "用户名: {$this->username}\n";
echo "密码: " . ($this->password ? "***(已隐藏)" : "(空密码)") . "\n";
echo "========================================\n";
}
private function printSuccess($result) {
echo "✅ 数据库连接成功!\n";
echo "连接耗时: {$result['connection_time']}ms\n";
echo "MySQL服务器版本: {$result['server_version']}\n";
echo "MySQL客户端版本: {$result['client_version']}\n";
echo "----------------------------------------\n";
}
private function printError($e) {
echo "❌ 数据库连接失败!\n";
echo "错误代码: " . $e->getCode() . "\n";
echo "错误信息: " . $e->getMessage() . "\n";
$this->printTroubleshooting($e->getCode());
echo "========================================\n";
}
private function printTroubleshooting($error_code) {
echo "\n常见问题排查:\n";
$suggestions = [
1045 => ["- 检查用户名和密码是否正确", "- 检查用户是否有远程访问权限"],
1049 => ["- 检查数据库名是否存在", "- 检查数据库名拼写是否正确"],
2002 => ["- 检查主机地址是否正确", "- 检查MySQL服务是否启动", "- 检查防火墙设置"],
2003 => ["- 检查端口是否正确", "- 检查MySQL服务是否启动", "- 检查防火墙设置"],
1044 => ["- 检查用户是否有访问该数据库的权限", "- 检查数据库权限设置"],
1698 => ["- 检查MySQL用户认证插件设置", "- 尝试使用mysql_native_password插件"],
1130 => ["- 检查MySQL用户的主机权限设置", "- 允许用户从当前主机连接"],
2013 => ["- 连接超时,检查网络状况", "- 检查MySQL服务器负载"]
];
if (isset($suggestions[$error_code])) {
foreach ($suggestions[$error_code] as $suggestion) {
echo "$suggestion\n";
}
} else {
echo "- 检查网络连接\n";
echo "- 检查MySQL服务状态\n";
echo "- 检查防火墙和网络安全组设置\n";
echo "- 检查密码中的特殊字符是否正确转义\n";
}
}
private function printFooter() {
echo "========================================\n";
echo "所有测试完成!数据库连接正常。\n";
echo "========================================\n";
}
}
// 更安全的命令行参数处理
function parseCommandLineArgs() {
global $argv;
$options = [
'host' => 'localhost',
'username' => 'root',
'password' => '',
'database' => 'test',
'port' => 3306
];
// 手动解析参数,避免getopt对特殊字符的处理问题
for ($i = 1; $i < count($argv); $i++) {
$arg = $argv[$i];
// 处理长选项 --option=value
if (strpos($arg, '--') === 0) {
$parts = explode('=', $arg, 2);
$key = substr($parts[0], 2);
$value = $parts[1] ?? '';
switch ($key) {
case 'host': $options['host'] = $value; break;
case 'user': $options['username'] = $value; break;
case 'password': $options['password'] = $value; break;
case 'database': $options['database'] = $value; break;
case 'port': $options['port'] = $value; break;
case 'help': showHelp(); exit(0);
}
}
// 处理短选项 -o value
elseif (strpos($arg, '-') === 0) {
$key = $arg[1];
$value = $argv[$i + 1] ?? '';
switch ($key) {
case 'h': $options['host'] = $value; $i++; break;
case 'u': $options['username'] = $value; $i++; break;
case 'p': $options['password'] = $value; $i++; break;
case 'd': $options['database'] = $value; $i++; break;
case 'P': $options['port'] = $value; $i++; break;
}
}
}
return $options;
}
// 交互式输入函数(用于安全输入密码)
function readPassword($prompt = "请输入密码: ") {
if (PHP_OS_FAMILY === 'Windows') {
echo $prompt;
// Windows系统隐藏输入比较困难,直接显示
$password = trim(fgets(STDIN));
} else {
// Linux/Mac系统可以使用stty隐藏输入
echo $prompt;
system('stty -echo');
$password = trim(fgets(STDIN));
system('stty echo');
echo "\n";
}
return $password;
}
function showHelp() {
echo "MySQL数据库连接测试工具\n\n";
echo "使用方法:\n";
echo " php " . basename(__FILE__) . " [选项]\n\n";
echo "选项:\n";
echo " -h, --host 数据库主机 (默认: localhost)\n";
echo " -u, --user 数据库用户名 (默认: root)\n";
echo " -p, --password 数据库密码 (建议用引号包裹特殊密码)\n";
echo " -d, --database 数据库名 (默认: test)\n";
echo " -P, --port 端口号 (默认: 3306)\n";
echo " --help 显示此帮助信息\n\n";
echo "密码特殊字符处理:\n";
echo " 如果密码包含特殊字符,请使用单引号或双引号包裹:\n";
echo " 正确: php script.php -p 'my@pass#word!'\n";
echo " 正确: php script.php -p \"my@pass#word!\"\n";
echo " 错误: php script.php -p my@pass#word!\n\n";
echo "示例:\n";
echo " php " . basename(__FILE__) . " -h 192.168.1.100 -u myuser -p 'my@pass#word!' -d mydb\n";
echo " php " . basename(__FILE__) . " --host=mysql.example.com --user=admin --password='your@password#'\n";
}
// 主程序
if (PHP_SAPI === 'cli') {
// 命令行模式
$config = parseCommandLineArgs();
// 如果密码为空,尝试交互式输入
if (empty($config['password'])) {
$config['password'] = readPassword();
}
$tester = new MySQLConnectionTester($config);
$success = $tester->testConnection();
exit($success ? 0 : 1);
} else {
// Web浏览器模式
echo "<pre>";
$config = [
'host' => $_POST['host'] ?? $_GET['host'] ?? 'localhost',
'username' => $_POST['user'] ?? $_GET['user'] ?? 'root',
'password' => $_POST['password'] ?? $_GET['password'] ?? '',
'database' => $_POST['database'] ?? $_GET['database'] ?? 'test',
'port' => $_POST['port'] ?? $_GET['port'] ?? 3306
];
$tester = new MySQLConnectionTester($config);
$tester->testConnection();
echo "</pre>";
}
?>