功能完整的MongoDB操作封裝類,支援多伺服器連線負載均衡、單例模式、索引管理、完整CRUD操作、條件查詢(分頁/排序/字段投影)、錯誤捕獲。適用於PHP 5.6+ 與舊版 MongoClient 驅動。
class NewMongodb {
private $mongo;
private $curr_db_name;
private $curr_table_name;
private $error;
public $config;
// 單例/連線池管理
public static function getInstance($mongo_server, $flag = []) {
static $instances = [];
$tag = $flag['tag'] ?? 'default';
if (isset($flag['force']) && $flag['force']) {
return $instances[$tag] = new self($mongo_server);
}
if (isset($instances[$tag]) && is_resource($instances[$tag])) {
return $instances[$tag];
}
return $instances[$tag] = new self($mongo_server);
}
// 建構子:支援多伺服器字串/陣列,自動負載均衡
public function __construct($mongo_server, $connect = true, $auto_balance = true) {
if (is_array($mongo_server)) {
$count = count($mongo_server);
if ($count > 1 && $auto_balance) {
$priority = rand(1, $count);
$keys = array_rand($mongo_server, $count);
$server_str = $mongo_server[$priority - 1];
foreach ($keys as $k) {
if ($k !== $priority - 1) $server_str .= ',' . $mongo_server[$k];
}
$mongo_server = $server_str;
} else {
$mongo_server = implode(',', $mongo_server);
}
}
try {
$this->mongo = new MongoClient($mongo_server, ['connect' => $connect]);
} catch (MongoConnectionException $e) {
$this->error = $e->getMessage();
return false;
}
}
// 選擇資料庫
public function selectDb($dbname) { $this->curr_db_name = $dbname; }
// 建立索引
public function ensureIndex($table, $index, $params = []) {
$params['safe'] = 1;
try {
$this->mongo->{$this->curr_db_name}->$table->ensureIndex($index, $params);
return true;
} catch (MongoCursorException $e) { $this->error = $e->getMessage(); return false; }
}
// 插入
public function insert($table, $record) {
try {
$this->mongo->{$this->curr_db_name}->$table->insert($record, ['safe' => true]);
return true;
} catch (MongoCursorException $e) { $this->error = $e->getMessage(); return false; }
}
// 統計
public function count($table) {
return $this->mongo->{$this->curr_db_name}->$table->count();
}
// 更新(支援 upsert/multiple)
public function update($table, $condition, $newdata, $options = []) {
$options['safe'] = 1;
$options['multiple'] = $options['multiple'] ?? 0;
try {
$this->mongo->{$this->curr_db_name}->$table->update($condition, $newdata, $options);
return true;
} catch (MongoCursorException $e) { $this->error = $e->getMessage(); return false; }
}
// 刪除(支援 justOne)
public function remove($table, $condition, $options = []) {
$options['safe'] = 1;
try {
$this->mongo->{$this->curr_db_name}->$table->remove($condition, $options);
return true;
} catch (MongoCursorException $e) { $this->error = $e->getMessage(); return false; }
}
// 查詢(支援分頁/排序/投影)
public function find($table, $query, $conditions = [], $fields = []) {
$cursor = $this->mongo->{$this->curr_db_name}->$table->find($query, $fields);
if (!empty($conditions['start'])) $cursor->skip($conditions['start']);
if (!empty($conditions['limit'])) $cursor->limit($conditions['limit']);
if (!empty($conditions['sort'])) $cursor->sort($conditions['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, $condition, $fields = []) {
return $this->mongo->{$this->curr_db_name}->$table->findOne($condition, $fields);
}
public function getError() { return $this->error; }
}
$mongo = NewMongodb::getInstance("127.0.0.1:27017");
$mongo->selectDb("test_db");
// 索引
$mongo->ensureIndex("users", ["email" => 1], ['unique' => true]);
// 插入
$mongo->insert("users", ["email" => "a@b.com", "name" => "John"]);
// 更新(upsert)
$mongo->update("users", ["email" => "a@b.com"], ["$set" => ["name" => "Jane"]], ["upsert" => 1]);
// 分頁查詢
$list = $mongo->find("users", ["age" => ['$gt' => 18]], ["start" => 0, "limit" => 10, "sort" => ["age" => 1]]);
// 單筆
$user = $mongo->findOne("users", ["email" => "a@b.com"]);
// 刪除單筆
$mongo->remove("users", ["email" => "a@b.com"], ["justOne" => 1]);
// 錯誤
if ($err = $mongo->getError()) { /* 處理 */ }
| 特性 | 實作細節 |
|---|---|
| 多伺服器負載均衡 | 建構子隨機打亂伺服器順序,優先連線隨機節點 |
| 連線池/單例 | getInstance() 以 tag 區分,支援強制重建 |
| 安全寫入 | 所有寫操作預設 safe=1 確認寫入 |
| 異常捕獲 | 統一捕獲 MongoCursorException、MongoConnectionException、MongoCursorTimeoutException |
| 靈活查詢 | 支援 skip/limit/sort/fields 投影 |
新版 MongoDB PHP 驅動 (1.10+) 已棄用 MongoClient,改用 MongoDB\Client。本類適用於舊版驅動專案維護,新專案建議使用官方 mongodb/mongodb Composer 套件。