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

PHP 實現 MongoDB 資料庫操作類完整版

     編輯:PHP 綜合知識

本文分享一個功能完整的 PHP MongoDB 操作類 HMongodb,支援多伺服器連線、自動負載均衡、單例模式管理,涵蓋 CRUD、索引管理、錯誤處理等核心功能,適合直接整合至專案中使用。

類架構設計亮點

  • 多伺服器容錯:支援陣列傳入多個 MongoDB 節點,單點故障自動切換
  • 負載均衡:隨機選擇優先節點,查詢均勻分發
  • 單例模式:透過標籤管理多實例,避免重複連線
  • 安全模式:所有寫操作預設啟用 safe = true 確認寫入成功

核心程式碼

<?php
class HMongodb {
    private $mongo;
    private $curr_db_name;
    private $curr_table_name;
    private $error;

    /** 取得單例實例
     * @param array|string $mongo_server 伺服器列表
     * @param array $flag 選項:tag(標識), force(強制新建)
     * @return HMongodb|false
     */
    public function getInstance($mongo_server, $flag = []) {
        static $mongodb_arr;
        $flag['tag'] = $flag['tag'] ?? 'default';

        if (($flag['force'] ?? false) === true) {
            $mongo = new HMongodb($mongo_server);
            $mongodb_arr[$flag['tag']] = $mongo;
            return $mongo;
        }

        if (isset($mongodb_arr[$flag['tag']]) && is_resource($mongodb_arr[$flag['tag']])) {
            return $mongodb_arr[$flag['tag']];
        }

        $mongo = new HMongodb($mongo_server);
        $mongodb_arr[$flag['tag']] = $mongo;
        return $mongo;
    }

    /** 建構子:支援多伺服器與負載均衡 */
    private function __construct($mongo_server, $connect = true, $auto_balance = true) {
        // 解析伺服器字串,支援 "host:port" 或陣列
        if (is_array($mongo_server)) {
            $count = count($mongo_server);
            if ($count > 1 && $auto_balance) {
                $prior = rand(1, $count);
                $keys = array_rand($mongo_server, $count);
                $server_str = $mongo_server[$prior - 1];
                foreach ($keys as $k) {
                    if ($k != $prior - 1) $server_str .= ',' . $mongo_server[$k];
                }
            } else {
                $server_str = implode(',', $mongo_server);
            }
        } else {
            $server_str = $mongo_server;
        }

        try {
            $this->mongo = new Mongo($server_str, ['connect' => $connect]);
        } catch (MongoConnectionException $e) {
            $this->error = $e->getMessage();
            return false;
        }
    }

    /** 手動連線 */
    public function connect() {
        try {
            $this->mongo->connect();
            return true;
        } catch (MongoConnectionException $e) {
            $this->error = $e->getMessage();
            return false;
        }
    }

    /** 選擇資料庫 */
    public function selectDb($dbname) {
        $this->curr_db_name = $dbname;
    }

    /** 建立索引 */
    public function ensureIndex($table_name, $index, $index_param = []) {
        $dbname = $this->curr_db_name;
        $index_param['safe'] = 1;
        try {
            $this->mongo->$dbname->$table_name->ensureIndex($index, $index_param);
            return true;
        } catch (MongoCursorException $e) {
            $this->error = $e->getMessage();
            return false;
        }
    }

    /** 插入文檔 */
    public function insert($table_name, $record) {
        $dbname = $this->curr_db_name;
        try {
            $this->mongo->$dbname->$table_name->insert($record, ['safe' => true]);
            return true;
        } catch (MongoCursorException $e) {
            $this->error = $e->getMessage();
            return false;
        }
    }

    /** 統計文檔數 */
    public function count($table_name) {
        $dbname = $this->curr_db_name;
        return $this->mongo->$dbname->$table_name->count();
    }

    /** 更新文檔 */
    public function update($table_name, $condition, $newdata, $options = []) {
        $dbname = $this->curr_db_name;
        $options['safe'] = 1;
        $options['multiple'] = $options['multiple'] ?? 0;
        try {
            $this->mongo->$dbname->$table_name->update($condition, $newdata, $options);
            return true;
        } catch (MongoCursorException $e) {
            $this->error = $e->getMessage();
            return false;
        }
    }

    /** 刪除文檔 */
    public function remove($table_name, $condition, $options = []) {
        $dbname = $this->curr_db_name;
        $options['safe'] = 1;
        try {
            $this->mongo->$dbname->$table_name->remove($condition, $options);
            return true;
        } catch (MongoCursorException $e) {
            $this->error = $e->getMessage();
            return false;
        }
    }

    /** 查詢多筆 */
    public function find($table_name, $query_condition, $result_condition = [], $fields = []) {
        $dbname = $this->curr_db_name;
        $cursor = $this->mongo->$dbname->$table_name->find($query_condition, $fields);

        if (!empty($result_condition['start'])) $cursor->skip($result_condition['start']);
        if (!empty($result_condition['limit'])) $cursor->limit($result_condition['limit']);
        if (!empty($result_condition['sort'])) $cursor->sort($result_condition['sort']);

        $result = [];
        try {
            while ($cursor->hasNext()) {
                $result[] = $cursor->getNext();
            }
        } catch (MongoConnectionException|MongoCursorTimeoutException $e) {
            $this->error = $e->getMessage();
            return false;
        }
        return $result;
    }

    /** 查詢單筆 */
    public function findOne($table_name, $condition, $fields = []) {
        $dbname = $this->curr_db_name;
        return $this->mongo->$dbname->$table_name->findOne($condition, $fields);
    }

    /** 取得錯誤訊息 */
    public function getError() {
        return $this->error;
    }
}

使用範例

<?php
// 初始化(單伺服器)
$mongo = HMongodb::getInstance("127.0.0.1:27017");
// 或多伺服器負載均衡
// $mongo = HMongodb::getInstance(["127.0.0.1:27017", "127.0.0.1:27018"]);

$mongo->selectDb("test_db");

// 建立唯一索引
$mongo->ensureIndex("users", ["email" => 1], ['unique' => true]);

// 插入
$mongo->insert("users", ["email" => "user@example.com", "name" => "張三"]);

// 更新(upsert)
$mongo->update("users", ["email" => "user@example.com"], ["name" => "李四"], ["upsert" => 1]);

// 分頁查詢
$list = $mongo->find("users", ["age" => ['$gt' => 18]], [
    'start' => 0,
    'limit' => 10,
    'sort' => ["created_at" => -1]
]);

// 單筆查詢
$user = $mongo->findOne("users", ["email" => "user@example.com"]);

// 刪除
$mongo->remove("users", ["email" => "user@example.com"], ["justOne" => 1]);

// 錯誤處理
if ($mongo->getError()) {
    error_log("MongoDB Error: " . $mongo->getError());
}

注意事項與升級建議

⚠ 重要提醒:本類基於舊版 Mongo 擴展(PHP 5.x 時代)。現代專案(PHP 7+)請改用官方 mongodb/mongodb 套件(Composer 安裝),新版 API 採用 MongoDB\Client、MongoDB\Database、MongoDB\Collection 等命名空間類別,功能更強大且持續維護中。

新版對應寫法速查

舊版 (Mongo)新版 (mongodb/mongodb)
new Mongo("localhost:27017")new MongoDB\Client("mongodb://localhost:27017")
$mongo->db->collection$client->db->collection
insert($doc, ['safe'=>true])insertOne($doc) / insertMany($docs)
update($cond, $new, ['multiple'=>1])updateMany($cond, ['$set' => $new])
find($cond)->limit(10)find($cond, ['limit' => 10])
ensureIndex($keys, $opts)createIndex($keys, $opts)

此類別雖屬舊版實作,但其單例管理、多伺服器容錯、錯誤封裝等設計思路仍具參考價值,可作為理解 MongoDB PHP 驅動封裝模式的教學案例。

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