1. PHP中使用MySQLi连接MySQL数据库的完整指南
作为PHP开发者,与MySQL数据库交互是日常开发中最基础也最重要的技能之一。MySQLi(MySQL Improved)扩展提供了比传统MySQL扩展更安全、更高效的操作方式。今天我将分享从基础连接到高级配置的完整实践方案,包含15年开发中积累的实用技巧。
1.1 为什么选择MySQLi而非MySQL扩展
MySQLi扩展自PHP 5.0引入,相比老旧的MySQL扩展具有三大核心优势:
- 面向对象和过程化双重接口:既支持面向对象的编程风格,也保留过程化写法,适应不同开发习惯
- 预处理语句支持:从根本上解决SQL注入问题,安全性大幅提升
- 事务处理能力:支持完整的ACID事务操作,适合金融级应用
重要提示:PHP 7.0已完全移除了MySQL扩展,使用新版PHP必须掌握MySQLi或PDO
1.2 基础连接参数详解
建立连接需要四个核心参数,每个都有特定配置要求:
$host = 'localhost'; // 可以是IP或域名 $user = 'app_user'; // 建议创建专用应用账号 $pass = 'S3cr3tP@ss'; // 至少12位混合字符 $db = 'inventory'; // 提前创建的数据库名连接超时配置技巧:
$mysqli = mysqli_init(); $mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5); // 5秒超时 $mysqli->real_connect($host, $user, $pass, $db);2. 连接MySQL的三种实战方式
2.1 面向对象风格(推荐)
$mysqli = new mysqli($host, $user, $pass, $db); if ($mysqli->connect_errno) { throw new RuntimeException("连接失败: ".$mysqli->connect_error); } // 设置字符集为UTF8MB4(支持emoji) if (!$mysqli->set_charset("utf8mb4")) { throw new RuntimeException("字符集设置失败: ".$mysqli->error); }2.2 过程化风格
$link = mysqli_connect($host, $user, $pass, $db); if (mysqli_connect_errno()) { die("连接失败: ".mysqli_connect_error()); } // 检查服务器状态 if (false === mysqli_ping($link)) { echo "连接已断开,正在重连..."; mysqli_close($link); $link = mysqli_connect($host, $user, $pass, $db); }2.3 持久连接方案
对于高并发场景,可使用p:前缀建立持久连接:
$mysqli = new mysqli('p:'.$host, $user, $pass, $db);注意:持久连接需要合理配置MySQL的wait_timeout和PHP的mysql.allow_persistent
3. 高级连接配置与优化
3.1 SSL加密连接配置
$mysqli = mysqli_init(); $mysqli->ssl_set( '/path/to/client-key.pem', '/path/to/client-cert.pem', '/path/to/ca-cert.pem', NULL, NULL ); $mysqli->real_connect($host, $user, $pass, $db);3.2 连接池实现方案
使用Swoole实现连接池的示例:
$pool = new Swoole\ConnectionPool( function() use ($host, $user, $pass, $db) { $mysqli = new mysqli($host, $user, $pass, $db); if ($mysqli->connect_errno) { return false; } return $mysqli; }, 100 // 连接池大小 );3.3 多主多从配置
$config = [ 'master' => ['host' => '192.168.1.10', 'user' => 'rw_user', 'pass' => 'RW_p@ss'], 'slaves' => [ ['host' => '192.168.1.11', 'user' => 'ro_user', 'pass' => 'RO_p@ss'], ['host' => '192.168.1.12', 'user' => 'ro_user', 'pass' => 'RO_p@ss'] ] ]; class DB { private static $writeConn; private static $readConn; public static function getWriteConnection() { if (!self::$writeConn) { self::$writeConn = new mysqli( $config['master']['host'], $config['master']['user'], $config['master']['pass'] ); } return self::$writeConn; } public static function getReadConnection() { if (!self::$readConn) { $slave = $config['slaves'][array_rand($config['slaves'])]; self::$readConn = new mysqli($slave['host'], $slave['user'], $slave['pass']); } return self::$readConn; } }4. 生产环境最佳实践
4.1 错误处理规范
推荐使用异常处理机制:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); try { $mysqli = new mysqli($host, $user, $pass, $db); // 业务代码... } catch (mysqli_sql_exception $e) { error_log("[DB_ERROR] ".$e->getMessage()); // 友好错误页面 http_response_code(500); exit("系统繁忙,请稍后再试"); }4.2 连接监控指标
关键监控指标及获取方式:
// 当前连接数 $status = $mysqli->query("SHOW STATUS LIKE 'Threads_connected'")->fetch_assoc(); // 查询缓存命中率 $variables = $mysqli->query("SHOW VARIABLES LIKE 'query_cache%'")->fetch_all(MYSQLI_ASSOC); // 连接使用率 $max_connections = $mysqli->query("SHOW VARIABLES LIKE 'max_connections'")->fetch_assoc(); $used_percent = ($status['Threads_connected'] / $max_connections['Value']) * 100;4.3 连接生命周期管理
推荐使用依赖注入容器管理连接:
class DBContainer { private static $instance; private $connection; private function __construct() { $this->connection = new mysqli($host, $user, $pass, $db); } public static function getInstance() { if (!self::$instance) { self::$instance = new self(); } return self::$instance->connection; } public function __destruct() { if ($this->connection) { $this->connection->close(); } } }5. 常见问题排查指南
5.1 连接失败排查流程
- 基础检查
telnet mysql_host 3306 - 权限验证
SELECT host, user FROM mysql.user; - 错误日志检查
tail -f /var/log/mysql/error.log
5.2 典型错误解决方案
| 错误代码 | 原因 | 解决方案 |
|---|---|---|
| 1045 | 认证失败 | 检查GRANT权限 |
| 2002 | 连接超时 | 检查防火墙设置 |
| 2006 | 服务器断开 | 增加wait_timeout |
| 2013 | 查询中断 | 优化复杂查询 |
5.3 性能优化参数
关键my.cnf配置建议:
[mysqld] max_connections = 500 wait_timeout = 300 interactive_timeout = 300 skip-name-resolve = ON6. 现代PHP框架中的连接实践
6.1 ThinkPHP连接配置
config/database.php示例:
return [ 'connections' => [ 'mysql' => [ 'type' => 'mysql', 'hostname' => env('DB_HOST', '127.0.0.1'), 'database' => env('DB_NAME', 'test'), 'username' => env('DB_USER', 'root'), 'password' => env('DB_PASS', ''), 'charset' => 'utf8mb4', 'debug' => true, 'break_reconnect' => true // 自动重连 ] ] ];6.2 Laravel连接池实现
通过扩展实现连接池:
// 在AppServiceProvider中注册 $this->app->singleton('db.connection.mysql', function ($app) { return new ConnectionPool( function () use ($app) { return $app['db.factory']->make($app['config']['database.connections.mysql']); }, $app['config']->get('database.pool.size', 50) ); });连接管理的最佳实践是在实际项目中根据具体需求选择合适的连接方式,并建立完善的监控机制。对于新项目,建议直接使用PDO或框架自带的数据库抽象层,它们通常已经实现了连接池、读写分离等高级特性。