collection = 'movies'; $cmd->pageno = 1; $count = -1; $rows = $mongo->get($cmd, $count); if ($rows === false) return clog($mongo->error); clog($count); foreach ($rows as $row) { clog($row); } return; * */ namespace ciy; class dbmongo { private $dbpst; private $linkdb; private $session; private $database; private $lastinsertid; private $isTransaction; public $error; function __construct($dbpst = '') { $this->linkdb = false; $this->dbpst = $dbpst; $this->isTransaction = false; $this->error = ''; } private function errdata($errmsg, $ret = false) { $this->error = $errmsg; return $ret; } private function connect() { if ($this->linkdb !== false) return $this->linkdb; $cfg = webini('mongodb' . $this->dbpst); if (is_string($cfg)) return $cfg; try { $uriOptions = []; $driverOptions = []; $this->linkdb = new \MongoDB\Driver\Manager( $cfg['uri'], $uriOptions, $driverOptions ); $pingCommand = new \MongoDB\Driver\Command(['ping' => 1]); $this->linkdb->executeCommand('admin', $pingCommand); $this->database = $cfg['name']; return $this->linkdb; } catch (\Exception $e) { return 'MongoDB connection failed: ' . $e->getMessage(); } } private function getTransactionOptions($defaultOptions = null): array { if ($this->isTransaction && $this->session) { return ['session' => $this->session]; } return $defaultOptions ? ['writeConcern' => $defaultOptions] : []; } /** * 获取查询的第一条数据 * * @param \stdClass $params 查询参数 * - collection: string 集合名 * - filter: array 查询条件 (可选) * - options: array 查询选项 (可选) * @return array|false 查询结果或false表示失败 */ public function getone(\stdClass $params) { try { $link = $this->connect(); if (is_string($link)) return $link; $params->options = $params->options ?? []; $params->options['limit'] = 1; $params->filter = $params->filter ?? []; $query = new \MongoDB\Driver\Query($params->filter, $params->options); $cursor = $link->executeQuery( "{$this->database}.{$params->collection}", $query, $this->getTransactionOptions() ); foreach ($cursor as $document) { return $document; } return null; } catch (\Exception $e) { return $this->errdata('Query getone failed: ' . $e->getMessage()); } } /** * 获取查询的多条数据(带分页) * * @param \stdClass $params 查询参数 * - collection: string 集合名 * - filter: array 查询条件 (可选) * - options: array 查询选项 (可选) * - pageno: int 页码 (默认1) * - pagecount: int 每页数量 (默认10) * @return \stdClass|false 包含数据和总数量的对象或false表示失败 */ public function get(\stdClass $params, &$rowcount = -1) { try { $link = $this->connect(); if (is_string($link)) return $link; $params->filter = $params->filter ?? new \stdClass(); $params->options = $params->options ?? []; $params->pageno = $params->pageno ?? 1; $params->pagecount = $params->pagecount ?? 10; if ($rowcount == -1) { $countCommand = new \MongoDB\Driver\Command([ 'count' => $params->collection, 'query' => $params->filter ]); $countResult = $link->executeCommand($this->database, $countCommand, $this->getTransactionOptions()); $rowcount = $countResult->toArray()[0]->n ?? 0; } $params->options['skip'] = ($params->pageno - 1) * $params->pagecount; $params->options['limit'] = $params->pagecount; // 执行查询 $query = new \MongoDB\Driver\Query($params->filter, $params->options); $cursor = $link->executeQuery( "{$this->database}.{$params->collection}", $query, $this->getTransactionOptions() ); return $cursor; } catch (\Exception $e) { return $this->errdata('Query get failed: ' . $e->getMessage()); } } /** * 插入数据 * * @param \stdClass $params 插入参数 * - collection: string 集合名 * - document: array 要插入的文档 * - options: array 插入选项 (可选) * @return int|false 插入数量或false表示失败 */ public function insert(\stdClass $params) { if (empty($params->document) || !is_array($params->document)) { return $this->errdata('Document must be provided and must be an array'); } try { $link = $this->connect(); if (is_string($link)) return $link; $bulk = new \MongoDB\Driver\BulkWrite(); $this->lastinsertid = $bulk->insert($params->document); $writeConcern = new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000); $writeResult = $link->executeBulkWrite("{$this->database}.{$params->collection}", $bulk, $this->getTransactionOptions($writeConcern)); if ($writeResult === false) { return $this->errdata('Write Error'); } return $writeResult->getInsertedCount(); } catch (\Exception $e) { return $this->errdata('Insert operation failed: ' . $e->getMessage()); } } public function insert_id() { return $this->lastinsertid; } /** * 更新数据 * * @param \stdClass $params 更新参数 * - collection: string 集合名 * - filter: array 查询条件 * - update: array 更新操作 * - options: array 更新选项 (可选) * @return int|false 更新的文档数量或false表示失败 */ public function update(\stdClass $params) { if (empty($params->filter) || !is_array($params->filter)) { return $this->errdata('Filter must be provided and must be an array'); } if (empty($params->update) || !is_array($params->update)) { return $this->errdata('Update must be provided and must be an array'); } try { $link = $this->connect(); if (is_string($link)) return $link; $bulk = new \MongoDB\Driver\BulkWrite(); $params->options = $params->options ?? []; if (!isset($params->options['multi'])) { $params->options['multi'] = false; } $bulk->update($params->filter, $params->update, $params->options); $writeConcern = new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000); $writeResult = $link->executeBulkWrite("{$this->database}.{$params->collection}", $bulk, $this->getTransactionOptions($writeConcern)); if ($writeResult === false) { return $this->errdata('Write Error'); } return $writeResult->getModifiedCount(); } catch (\Exception $e) { return $this->errdata('Update operation failed: ' . $e->getMessage()); } } /** * 删除数据 * * @param \stdClass $params 删除参数 * - collection: string 集合名 * - filter: array 查询条件 * - options: array 删除选项 (可选) * @return int|false 删除的文档数量或false表示失败 */ public function delete(\stdClass $params) { if (empty($params->filter) || !is_array($params->filter)) { return $this->errdata('Filter must be provided and must be an array'); } try { $link = $this->connect(); if (is_string($link)) return $link; $bulk = new \MongoDB\Driver\BulkWrite(); $params->options = $params->options ?? []; if (!isset($params->options['limit'])) { $params->options['limit'] = false; } $bulk->delete($params->filter, $params->options); $writeConcern = new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000); $writeResult = $link->executeBulkWrite("{$this->database}.{$params->collection}", $bulk, $this->getTransactionOptions($writeConcern)); if ($writeResult === false) { return $this->errdata('Write Error'); } return $writeResult->getDeletedCount(); } catch (\Exception $e) { return $this->errdata('Delete operation failed: ' . $e->getMessage()); } } /** * 开始事务 * @return bool 是否成功 */ public function begin() { if ($this->isTransaction) { return $this->errdata('Transaction already started'); } try { $link = $this->connect(); if (is_string($link)) return $link; $this->session = $link->startSession(); $this->session->startTransaction(); $this->isTransaction = true; return true; } catch (\Exception $e) { return $this->errdata('Failed to start transaction: ' . $e->getMessage()); } } /** * 提交事务 * @return bool 是否成功 */ public function commit() { if (!$this->isTransaction) { return $this->errdata('No active transaction to commit'); } try { $this->session->commitTransaction(); $this->session->endSession(); $this->isTransaction = false; return true; } catch (\Exception $e) { $this->isTransaction = false; return $this->errdata('Failed to commit transaction: ' . $e->getMessage()); } } /** * 回滚事务 * @return bool 是否成功 */ public function rollback() { if (!$this->isTransaction) { return $this->errdata('No active transaction to rollback'); } try { $this->session->abortTransaction(); $this->session->endSession(); $this->isTransaction = false; return true; } catch (\Exception $e) { $this->isTransaction = false; return $this->errdata('Failed to rollback transaction: ' . $e->getMessage()); } } public function tran($func) { if (!($func instanceof \Closure)) { $this->error = '没有传递正确的闭包函数'; return false; } $this->begin(); $ret = false; try { $ret = $func(); } catch (\Exception $ex) { $ret = false; $this->error = $ex->getMessage(); } if ($ret === false) $this->rollback(); else $this->commit(); return $ret; } }