首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

PHP 連接 MySQL 完整指南:mysqli 面向對象、預處理語句、事務控制、連接池

     編輯:MySQL 綜合教學

PHP 操作 MySQL 現代最佳實踐:mysqli 面向對象 API 全解析

棄用古老 mysql_* 函數(PHP 7.0 移除),採用 mysqli 面向對象 或 PDO,配合預處理語句、事務、連接池,構建安全高效數據層。

一、mysqli 核心操作流程

// 1. 連接
$mysqli = new mysqli('localhost', 'root', 'pass', 'test', 3306);
if ($mysqli->connect_errno) {
    die("Connect failed: " . $mysqli->connect_error);
}

// 2. 設置字符集(關鍵!防亂碼)
$mysqli->set_charset('utf8mb4');

// 3. 預處理語句(防注入、性能優)
$stmt = $mysqli->prepare("SELECT id, name, email FROM users WHERE status = ? AND created_at > ?");
$stmt->bind_param('is', $status, $date);  // i=integer, s=string, d=double, b=blob
$status = 1;
$date = '2024-01-01';
$stmt->execute();

// 4. 綁定結果
$stmt->bind_result($id, $name, $email);
while ($stmt->fetch()) {
    echo "ID: $id, Name: $name, Email: $email\n";
}
$stmt->close();

// 5. 事務控制
$mysqli->begin_transaction();
try {
    $stmt = $mysqli->prepare("INSERT INTO orders (user_id, amount) VALUES (?, ?)");
    $stmt->bind_param('id', $uid, $amt);
    foreach ($orders as $o) {
        $uid = $o['uid']; $amt = $o['amt'];
        $stmt->execute();
    }
    $stmt->close();
    $mysqli->commit();
} catch (Exception $e) {
    $mysqli->rollback();
    throw $e;
}

// 6. 關閉連接
$mysqli->close();

二、關鍵最佳實踐

實踐代碼/配置理由
預處理語句$stmt->bind_param()防 SQL 注入、預編譯緩存、類型安全
顯式字符集$mysqli->set_charset('utf8mb4')避免亂碼、支持 Emoji
錯誤模式異常$mysqli->report_mode = MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT自動拋出異常,無需手動檢查 errno
事務原子性begin_transaction()/commit()/rollback()保證數據一致性
批量操作multi_query() 或 循環 execute()減少網絡往返
獲取自增 ID$mysqli->insert_idINSERT 後立即獲取

三、連接池方案(生產環境必須)

PHP-FPM 多進程模式下,每進程維護連接池。推薦方案:

  • Swoole 協程池:Swoole\Coroutine\MySQL 連接池,高併發首選
  • Workerman/GlobalData:長連接進程池
  • 傳統方案:每請求建連,配合 mysqli::real_connect 持久連接 p: 前綴(慎用,易洩漏)
// Swoole 協程連接池示例
$pool = new Swoole\Coroutine\MySQL\Pool(
    (object)[
        'host' => '127.0.0.1', 'port' => 3306,
        'user' => 'root', 'password' => 'pass', 'database' => 'test',
        'charset' => 'utf8mb4'
    ],
    20  // 最大連接數
);

go(function () use ($pool) {
    $db = $pool->get();
    $result = $db->query("SELECT * FROM users LIMIT 10");
    $pool->put($db);
});

四、PDO 替代方案(跨數據庫)

$pdo = new PDO(
    'mysql:host=localhost;dbname=test;charset=utf8mb4',
    'root', 'pass',
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
     PDO::ATTR_EMULATE_PREPARES => false,  // 真實預處理
     PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
);

$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
$user = $stmt->fetch();

五、常見坑點避坑指南

  1. 未設置字符集 → 亂碼/Emoji 存入失敗
  2. 字符串拼接 SQL → SQL 注入漏洞
  3. 未關閉預處理語句 → 內存洩漏、達到 max_prepared_stmt_count 限制
  4. 事務中混用 DDL → 隱式提交,破壞原子性
  5. 長連接不驗證 → "server has gone away"

現代 PHP 專案建議:Hyperf/Laravel/Symfony 框架內置 DBAL/ORM,底層封裝 PDO/mysqli,提供查詢構建器、遷移、種子、模型關聯,專注業務邏輯而非 SQL 拼接。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved