MongoDB for PHP擴充套件操作類
阿新 • • 發佈:2018-12-24
- <?php
- /**
- *
- * @link https://github.com/thendfeel/TmongoDB
- * @example
- * @copyright
- * @site http://www.uacool.com
- * @created 2013-12-13
- *
- * Manual
- * http://us2.php.net/mongo
- * 針對阿里雲MongoDB資料庫
- * SQL to Mongo Mapping Chart
- * http://us2.php.net/manual/en/mongo.sqltomongo.php
- * 單例模式(只針對相同的config)
- */
- class TmongoDB
- {
- protected$_db = 'test';
- protected$_collection = 'user';
- protected$_validate = array();
- protectedstatic$_mongoObj = array();
- private$_exeResult = null;
- protected$_sql = array();
- protected$_mongo = null;
- const CONNECT_DB = 'admin'; // 連線資料庫,預設為admin
- /**
- * Config For MongDB
- *
- * @var array
- */
- protected$_config = array(
- 'mongo_seed1' => 'localhost',
- 'mongo_seed2' => '',
- 'mongo_replname' => '',
- 'mongo_user' => NULL,
- 'mongo_pwd' => NULL
- );
- publicfunction __construct($config,$db, $collection)
- {
- foreach ($this->_config as$k => $v) {
- if(isset($config[$k])){
- $this->_config[$k] = $config[$k];
- } else {
- E('mongoDB資料庫連線,請傳遞'.$k);
- }
- }
- $this->_db = $db;
- $this->_collection = $collection;
- $this->init();
- }
- publicfunction getMongo()
- {
- return$this->_mongo;
- }
- /**
- * Init The Class
- * 對於相同的配置只初始化一次
- * @param string $db
- * @param string $collection
- */
- publicfunction init()
- {
- $config = $this->_config;
- ksort($config);
- $encryptStr = '';
- foreach ($configas$k => $v) {
- $encryptStr .= ($k.$v);
- }
- $key = md5($encryptStr);
- if (!self::$_mongoObj[$key]) {
- /*$conStr = "mongodb://";
- if ($config['user'] && $config['password']) {
- $conStr .= "{$config['user']}:{$config['password']}@";
- }
- $conStr .= "{$config['host']}:{$config['port']}";
- $_mongoDB = new \Mongo($conStr, array(
- "connect" => false
- ));*/
- $demo_uri = 'mongodb://' . $config['mongo_user'] . ':' . $config['mongo_pwd'] . '@' .
- $config['mongo_seed1'] . ',' . $config['mongo_seed2'] . '/' . self::CONNECT_DB . '?replicaSet=' . $config['mongo_replname'];
- $manager = new \MongoDB\Driver\Manager($demo_uri);
- self::$_mongoObj[$key] = $this->_mongo = $manager;
- /*if ($db && $collection) {
- $this->_mongoDB = $_mongoDB->selectCollection($db, $collection);
- } else {
- $this->_mongoDB = $_mongoDB->selectCollection($this->_db,$this->_collection);
- }*/
- } else {
- $this->_mongo = self::$_mongoObj[$key];
- }
- }
- /**
- * Set Db & Collection
- * 重新設定資料庫和資料表
- * @param string $db
- * @param string $collection
- */
- publicfunction setDb($db = NULL, $collection = NULL)
- {
- if ($db) {
- $this->_db = $db;
- //$this->_mongoDB = NULL;
- //$this->_mongoDB = $this->_mongoObj->selectCollection($this->_db,$this->_collection);
- }
- if ($collection) {
- $this->_collection = $collection;
- }
- return$this;
- }
- /**
- * Set Collection
- * 重新設定資料表
- * @param string $collection
- */
- publicfunction setCollection($collection = NULL)
- {
- if ($collection) {
- $this->_collection = $collection;
- //$this->_mongoDB = NULL;
- //$this->_mongoDB = $this->_mongoObj->selectCollection($this->_db,$collection);
- }
- return$this;
- }
- /**
- * 獲取指定條件下的集合裡的資料數量,預設使用_id主鍵欄位
- */
- publicfunctioncount($argv = array(),$fields = '_id')
- {
- $result = $this->find($argv,$fields);
- if ($result) {
- returncount($result);
- } else {
- return 0;
- }
- }
- /**
- * Fetch From Mongodb
- *
- * @param array $argv
- * @param number $skip
- * @param number $limit
- * @param array $sort
- * @return Ambigous <multitype:, multitype:>|boolean
- */
- publicfunction find($argv = array(),$fields = array(),$sort = array(),$skip = 0, $limit = 0)
- {
- /*$argv = $this->validate($argv);
- if ($argv) {
- $result = $this->_mongoDB->find($argv)
- ->skip($skip)
- ->limit($limit)
- ->sort($sort);
- return self::toArray($result);
- }*/
- $options = array();
- if ($skip) {
- $options['skip'] = $skip;
- }
- if ($limit) {
- $options['limit'] = $limit;
- }
- if ($sort) {
- $options['sort'] = $sort;
- }
- if ($fields) {
- if (is_string($fields)) {
- $fields = explode(',', $fields);
- }
- foreach ($fieldsas$v) {
- $options['projection'][$v] = 1;
- }
- }
- $query = new \MongoDB\Driver\Query($argv, $options);
- $cursor = $this->_mongo->executeQuery($this->_db.'.'.$this->_collection, $query);
- return$cursor->toArray();
- }
- /**
- * 執行命令
- */
- publicfunction runCommand($command = array())
- {
- if (!$command) {
- return false;
- }
- $commandObj = new \MongoDB\Driver\Command($command);
- try {
- $cursor = $this->_mongo->executeCommand($this->_db, $commandObj);
- $response = $cursor->toArray();
- } catch(\MongoDB\Driver\Exception $e) {
- echo'Mongo的runCommand異常:',$e->getMessage();
- exit;
- }
- if (count($response) > 1) {
- return$response;
- } else {
- return$response[0];
- }
- }
- /**
- * Fetch By MongoId
- *
- * @param string $_id
- * @return Ambigous <Ambigous, boolean, multitype:>
- */
- publicfunction findById($_id = '',$fields = array())
- {
- if (is_string($_id)) {
- return$this->findOne(array('_id' => new \MongoDB\BSON\ObjectID($_id)),$fields);
- }
- }
- /**
- * Fetch One From MongoDB
- *
- * @param array $argv
- * @param array $fields
- * @return multitype: boolean
- */
- publicfunction findOne($argv = array(),$fields = array(),$sort = array())
- {
- $result = $this->find($argv,$fields,$sort,0,1);
- if ($result) {
- return$result[0];
- } else {
- return NULL;
- }
- //return $this->cleanId($this->_mongoDB->findOne($argv, $fields));
- }
- /**
- * Update MongoDB By Id
- * 通過主鍵ID更新
- * @param string $_id
- * @param array $newData
- */
- publicfunction updateById($_id, $set = array())
- {
- return$this->updateStatement(array('_id' => new \MongoDB\BSON\ObjectID($_id)), array('$set'=>$set))->execute()->getModifiedCount();
- }
- /**
- * 執行新增,刪除,更新 All From Mongodb,執行多個語句
- * $obj->deleteStatement(array('name'=>'1'))->deleteStatement(array('id'=>1))->remove();
- * @param array $argv
- */
- publicfunction execute()
- {
- if (!$this->_sql) {
- return NULL;
- }
- $bulk = new \MongoDB\Driver\BulkWrite;
- foreach ($this->_sql as$val) {
- switch ($val['type']) {
- case'delete':
- $bulk->delete($val['sql'],$val['limit']);
- break;
- case'insert':
- $bulk->insert($val['document']);
- break;
- case'update':
- $bulk->update($val['filter'],$val['set'],$val['options']);
- break;
- }
- }
- $writeConcern = new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000);
- try {
- $this->_exeResult = $this->_mongo->executeBulkWrite($this->_db.'.'.$this->_collection, $bulk, $writeConcern);
- } catch(\MongoDB\Driver\Exception\WriteException $e) {
- echo'MongoDB擴充套件寫入異常:';
- $writeResult = $e->getWriteResult();
- if ($writeConcernError = $writeResult->getWriteConcernError()) {
- echo$writeConcernError[0]->getMessage(),'<br />';
- }
- if ($writeErrors = $writeResult->getWriteErrors()) {
- echo$writeErrors[0]->getMessage();
- }
- exit();
- } catch (\MongoDB\Driver\Exception\InvalidArgumentException $e) {
- exit('MongoDB擴充套件傳入引數異常:'.$e->getMessage());
- } catch (\MongoDB\Driver\Exception\RuntimeException $e) {
- exit('MongoDB擴充套件執行異常:'.$e->getMessage());
- } catch (\MongoDB\Driver\Exception\ExecutionTimeoutException $e) {
- exit('MongoDB擴充套件執行超時異常:'.$e->getMessage());
- } catch (\MongoDB\Driver\Exception\ConnectionTimeoutException $e) {
- exit('MongoDB擴充套件連線超時異常:'.$e->getMessage());
- } catch (\Exception $e) {
- exit('系統異常:'.$e->getMessage());
- }
- return$this;
- }
- /**
- * 獲取刪除的行數
- */
- publicfunction getDeletedCount()
- {
- if ($this->_exeResult) {
- return$this->_exeResult->getDeletedCount();
- } else {
- return 0;
- }
- }
- /**
- * 獲取實際更新的行數
- */
- publicfunction getModifiedCount()
- {
- if ($this->_exeResult) {
- return$this->_exeResult->getModifiedCount();
- } else {
- return 0;
- }
- }
- /**
- * 一次最多插入9萬條以下.耗時
- * 獲取實際插入的行數
- */
- publicfunction getInsertedCount()
- {
- if ($this->_exeResult) {
- return$this->_exeResult->getInsertedCount();
- } else {
- return 0;
- }
- }
- /**
- * 獲取實際匹配的行數
- */
- publicfunction getMatchedCount()
- {
- if ($this->_exeResult) {
- return$this->_exeResult->getMatchedCount();
- } else {
- return 0;
- }
- }
- /**
- * 獲取實際更新失敗然後新插入的行數
- *
- */
- publicfunction getUpsertedCount()
- {
- if ($this->_exeResult) {
- return$this->_exeResult->getUpsertedCount();
- } else {
- return 0;
- }
- }
- /**
- * 獲取實際更新失敗然後新插入的ID列表
- */
- publicfunction getUpsertedIds()
- {
- if ($this->_exeResult) {
- return$this->_exeResult->getUpsertedIds();
- } else {
- return 0;
- }
- }
- /**
- * delete子句
- * @param $delete 為刪除過濾條件,為陣列形式
- */
- publicfunction deleteStatement($delete,$limit = 0)
- {
- $this->_sql[] = array('type'=>'delete','sql'=>$delete,'limit'=>array('limit'=>$limit));
- return$this;
- }
- /**
- * insert子句
- * @param $batch 批量插入資料
- */
- publicfunction insertStatement($insert,$batch = false)
- {
- if ($batch) {
- if (is_array($insert) && $insert) {
- foreach ($insertas$val) {
- $this->_sql[] = array('type'=>'insert','document'=>$val);
- }
- }
- } else {
- $this->_sql[] = array('type'=>'insert','document'=>$insert);
- }
- return$this;
- }
- /**
- * update子句
- * @param option multi 為true則更新全部符合條件的文件,否則只更新一個符合條件的文件
- * upsert 為true則當沒有符合條件的文件時將更新過後的資料插入到集合中
- * 參考連線:http://blog.csdn.net/qq1355541448/article/details/9082225
- * 第二個引數有以下的做法:
- * 修改更新
- * 使用set關鍵字: $set:讓某節點等於給定值 ,欄位不變,內容變了
- * 替換更新:
- * 第一個引數$where=array(‘column_name’=>’col709′),第二個引數:$newdata=array(‘column_exp’=>’HHHHHHHHH’,'column_fid’=>123);
- * 那麼指定的column_name欄位將會替換成成column_exp(=HHHHHHHHH)和column_fid(123)
- * 自動累加或自動累減
- * array(‘$set’=>$newdata,’$inc’=>array(’91u’=>-5),第二個引數,在找到的91u欄位的引數會自動在原值減5
- * 刪除指定欄位
- * $where=array(‘column_name’=>’col685′);
- * $result=$collection->update($where,array(‘$unset’=>’column_exp’));column_exp欄位將會被刪除
- * 參考文件:https://docs.mongodb.org/manual/reference/operator/update/
- */
- publicfunction updateStatement($filter,$set,$options = array('multi' => true, 'upsert' => false))
- {
- $this->_sql[] = array('type'=>'update','filter'=>$filter,'set'=>$set,'options'=>$options);
- return$this;
- }
- /**
- * Remove By Id From Mongodb
- *
- * @param string $_id
- * @return Ambigous <boolean, multitype:>
- */
- publicfunction removeById($_id)
- {
- return$this->deleteStatement(array('_id' => new \MongoDB\BSON\ObjectID($_id)))->execute()->getDeletedCount();
- }
- /**
- * Remove One From Mongodb
- *
- * @param array $argv
- */
- publicfunction removeOne($argv = array())
- {
- return$this->deleteStatement($argv,1)->execute()->getDeletedCount();
- }
- /**
- * Remove Field From MongoDB
- *
- * @param string $_id
- * @param array $field
- */
- // public function removeFieldById($_id, $field = array())
- // {
- // return $this->updateStatement(array('_id' => new \MongoDB\BSON\ObjectID($_id)), array('$unset' => $unSetfield));
- // }
- /**
- * Validate Data Callbak Function 沒有用到的函式
- *
- * @param array $argv
- */
- privatefunction validate($data)
- {
- if ($this->_validate) {
- foreach ($this->_validate as$arg => $validate) {
- if (is_array($data) && array_key_exists(strval($arg), $data)) {
- foreach ($validateas$key => $value) {
- switch (strtolower($key)) {
- case'type':
- if ($value == 'int') {
- $data[$arg] = (int) $data[$arg];
- } elseif ($value == 'string') {
- $data[$arg] = (string) $data[$arg];
- } elseif ($value == 'bool') {
- $data[$arg] = (bool) $data[$arg];
- } elseif ($value == 'float') {
- $data[$arg] = (float) $data[$arg];
- } elseif ($value == 'array') {
- $data[$arg] = (array) $data[$arg];
- }
- break;
- case'min':
- if (strlen($data[$arg]) < $value) {
- exit('Error: The length of ' . $arg . ' is not matched');
- }
- break;
- case'max':
- if (strlen($data[$arg]) > $value) {
- exit('Error: The length of ' . $arg . ' is not matched');
- }
- break;
- case'func':
- $call = preg_split('/[\:]+|\-\>/i', $value);
- if (count($call) == 1) {
- $data[$arg] = call_user_func($call['0'], $data[$arg]);
- } else {
- $data[$arg] = call_user_func_array(array($call['0'],$call['1']), array($data[$arg]));
- }
- break;
- }
- }
- }
- }
- }
- return$data;
- }