php mongo 类,mongo php类

/**

* mongo 类

* User: wujp 

* Date: 13-10-12

* Time: 下午5:48

*/

class Mongo_DB

{

#链接

public $conn = null;

#mongodb

public $db = null;

#链接参数

private $url = '';

#判断db是否链接

private $collected = null;

#查询、更新 映射 有|

private $four_map = array( #值是字符串,值不用处理

'>' => '$gt',

'>=' => '$gte',

' '$le',

'<=' => '$lte',

'!=' => '$ne',

'@' => '$exists', #键是否存在

'?' => 'perl', #正则

);

private $ele_map = array( #数组,值需要处理

'~' => '$elemMatch' #内嵌文档

);

private $log_map = array( #值必须是数组

'^' => '$in',

'!^' => '$nin',

'*' => '$all', #指定数组元素

);

#没有|

private $lgi_map = array( #必须是二维数组

'$' => '$or',

'&' => '$and',

);

private $where_map = array(

'%' => '$where', #javascript 函数

);

private $sort_map = array(

'DESC' => -1,

'ASC' => 1

);

#当前db下所有集合=>键数组

public $collections = null;

#基本配置参数

private $config = array(

'host' => 'localhost',

'port' => '27017',

'dbname' => '',

'user' => '',

'pass' => '',

'logpath' => '', #日志目录

'replicaset' => array( #集群

'host' => array()

//            'host' => array('host:port'), #主机群

//            'options' => array('readPreference', 'readPreferenceTags', 'replicaSet','slaveok')

),

);

/**

* 构造函数,基本参数设置

* @param $config

*

*/

public function __construct($config)

{

if (is_array($config) && $config) {

foreach ($this->config as $k => $v) {

if (isset($config[$k]) && $config[$k])

$this->config[$k] = !is_array($config[$k]) ? trim($config[$k]) : $config[$k];

}

$this->connect();

}

}

/**

* 初始化mongo

*

*/

private function connect()

{

if (!extension_loaded('mongo'))

exit('ERROR:MONGO EXTENSION NOT LOAD');

if ($this->conn === NULL) {

try {

if ($this->config['replicaset']['host']) {

#todo 主从配置,或者副本集,读扩展,

} else {

$this->url .= "mongodb://{$this->config['user']}:{$this->config['pass']}@{$this->config['host']}:

{$this->config['port']}/{$this->config['dbname']}";

$this->conn = new MongoClient($this->url);

}

$this->db = $this->conn->selectDB($this->config['dbname']);

if ($this->db) {

$this->collected = true;

$this->GetAllCollection(); #获取所有集合列表

}

} catch (MongoConnectionException $e) {

$this->ErrLog($e->getMessage());

exit('MONGO CONNECT ERROR');

}

}

}

/**

* 析构函数

*/

public function __destruct()

{

$this->collected = $this->collections = $this->db = $this->conn = null;

}

/**

* 获取db下所有集合名称

*

* @internal param $dbname

* @return bool

*/

private function GetAllCollection()

{

if (!$this->collected)

return false;

$colls = $this->db->listCollections();

if ($colls) {

foreach ($colls as $v) {

$pos = strpos($v, $this->config['dbname']);

if ($pos !== false)

$this->collections[] = substr($v, ($pos + strlen($this->config['dbname']) + 1));

}

return true;

} else {

return false;

}

}

/**

* 初始化集合对象

* @param $collname 集合名

* @return mixed

*/

public function GetMonCollection($collname)

{

if (!$this->collected)

return false;

return $this->db->selectCollection($collname);

}

/**

* 转换字符编码

* @param $array

* @return bool

*/

private function ConvertEncode($array)

{

if (is_array($array)) {

foreach ($array as &$v) {

if (is_array($v)) {

$v = $this->ConvertEncode($v);

if (!$v)

return false;

} else {

$code = mb_detect_encoding($v, array('UTF-8', 'ASCII', 'GB2312', 'GBK', 'CP936'), true);

if ($code !== 'UTF-8')

$v = mb_convert_encoding($v, 'UTF-8', $code);

}

}

return $array;

}

return false;

}

/**

* 获取where参数

* @param $where

* @param bool $type

* @return string

*

*/

private function GetWhere($where, $type = false)

{

$wheres = array();

$maps = array('four_map', 'log_map', 'ele_map');

$maps_np = array_merge($this->lgi_map, $this->where_map);

if (is_array($where) && $where) { #过滤查询条件

foreach ($where as $field => $val) {

$pos = strpos($field, '|');

if ($pos !== false) { #四则、正则、函数、数组、in、多重条件内嵌文档

$tep = substr($field, 0, $pos);

$key = substr($field, ($pos + 1));

if ($key !== false) {

foreach ($maps as $v) {

$arr = $this->$v;

if (in_array($tep, array_keys($arr))) {

if ($v == 'ele_map' && is_array($val))

$val = $this->GetWhere($val, true);

if ($tep == '?') { #正则

$val = new MongoRegex($val);

$wheres[$key] = $val;

} else {

$wheres[$key][$arr[$tep]] = $val;

}

}

}

}

} elseif (in_array($field, array_keys($maps_np))) {

if (in_array($field, array_keys($this->lgi_map)) && is_array($val)) { #逻辑

foreach ($val as $v) {

$val = $this->GetWhere($v, true);

$wheres[$maps_np[$field]][] = $val;

}

} else {

$wheres[$maps_np[$field]] = $val;

}

} else { #普通查询、单一条件内嵌文档

if (strpos($field, "[") !== false)

$field = str_replace("[", ".", $field);

if (is_array($val) && $type) {

$arr = $this->GetWhere($val);

foreach ($arr as $k => $v) {

$wheres[$k][] = $v;

}

} elseif (is_null($val)) {

$wheres[$field] = array('$in' => array(null), '$exists' => 1);

} else {

$wheres[$field] = $val; #支持 array('age'=>array('>'=>'18','<='=>'20'))

}

}

}

}

return $wheres;

}

/**

* 插入一行

* @param $collect

* @param $value

* @return bool

*/

public function InsOne($collect, $value)

{

if (!$this->collected || !is_array($value))

return false;

$id = array_search('id', array_keys($value)); #处理有id字段的情况

if ($id !== false && array_search('_id', array_keys($value)) === false) {

$value['_id'] = $value['id'];

unset($value['id']);

}

$value = $this->ConvertEncode($value);

if (!$value)

return false;

try {

$result = $this->GetMonCollection($collect)->insert($value);

$result = $result['err'] ? false : true;

} catch (MongoException $e) {

$this->ErrLog($e->getMessage());

return false;

}

return $result;

}

/**

* 插入多行

* @param $collect 集合

* @param $fields

* @param $values 键值对:array(0=>array(''=>''))

* @param bool $continueOnError 是否忽略插入错误,默认忽略

* @return bool

*/

public function InsMulit($collect, $fields, $values, $continueOnError = false)

{

if (!is_array($fields) || !is_array($values) || !$this->collected)

return false;

$id = array_search('id', $fields); #处理有id字段的情况

if ($id !== false && array_search('_id', $fields) === false)

$fields[$id] = '_id';

$data = array();

$values = $this->ConvertEncode($values);

if ($values) {

foreach ($values as $v) {

if (is_array($v)) {

$v = array_combine($fields, $v);

if ($v)

$data[] = $v;

}

}

}

if (!$data)

return false;

$option['continueOnError'] = $continueOnError ? true : false;

try {

$result = $this->GetMonCollection($collect)->batchinsert($data, $option);

$result = $result['err'] ? false : true;

} catch (MongoException $e) {

$this->ErrLog($e->getMessage());

return false;

}

return $result;

}

/**

* 查询一个

* @param $collect

* @param array $where

* @param $field string

* @return bool

*/

function FindOne($collect, $where = array(), $field)

{

if (!$this->collected)

return false;

$wheres = $this->GetWhere($where);

if ($where && !$wheres)

return false;

if (is_string($field) && trim($field))

$field = trim($field);

else

return false;

$result = $this->GetMonCollection($collect)->findOne($wheres, array($field));

if ($result) {

$arr = get_object_vars($result['_id']);

$result['_id'] = $arr['$id'];

return $result[$field];

}

return false;

}

/**

* 查询一条

* @param $collect

* @param array|string $where

* @param array $fields

* @param string $type

* @return array|bool

*/

function FindRow($collect, $where = array(), $fields = array(), $type = 'assoc')

{

if (!$this->collected)

return false;

$wheres = $this->GetWhere($where);

if ($where && !$wheres)

return false;

if ($fields && is_array($fields)) { #过滤fields

$val = '';

for ($i = 0; $i 

$val[] = 1;

}

$fields = array_combine($fields, $val);

} else {

$fields = array();

}

$result = $this->GetMonCollection($collect)->findOne($wheres, $fields);

if ($result) {

if (in_array('_id', $fields)) {

$arr = get_object_vars($result['_id']);

$result['_id'] = $arr['$id'];

} else {

unset($result['_id']);

}

if (strtolower($type) == 'array')

$result = array_values($result);

return $result;

}

return false;

}

/**

* 复合查询  todo 查询高级选项扩展 snapshot maxscan  min max hint explain

* $gt:>|$gte:>=|$le:

* array('x'=>array('$gt'=>'20'))

*

* $or:$|$end:&

* array('x'=>array('$in'=>array('1','2')))

*

* $where:%

* array('x'=>array('$where'=>function))

*

* 正则表达式:

* ?

*

* 数组:

* $all:*

*

* 内嵌文档:

* 单个条件:username.user   username[user

* 多个条件:$elemMatch

*

* 逻辑操作符:

* not:!

* or:$

* end:&

* sort

* array('x'=>0)

*

* limit|skip

* $where = array('&|'=>array('she_hash' => '48b6c531ef2469469ede4ac21eebcf51', 'type' => 'doing'));

* $field = array('time', '_id' => 0);

* $res = $mongo->FindMix('sapilog', $where, $field,'1,2',array('time'=>'desc'));

* ------------------------->

* @param $collect |string

* @param string $where |array array('>|x'=>'10','<=|x'=>'20','^|x'=>array(),'%|x'=>'fun')

* @param array|string $fields |array|string 返回字段 默认为全部 字符串返回一个字段,键为数字则为返回该字段,键为字段,值为-1为不返回该字段

* @param string $limit |string  skip,limit  0,10 如果没有 默认 skip为0 limit为当前变量

* @param string $sort |array array('x'=>'desc|asc') desc=>-1 asc=>

* @param string $type  | string 返回类型 默认为关联数组 assoc|array

* @return bool

*/

public function FindMix($collect, $where = '', $fields = array(), $limit = '', $sort = '', $type = 'assoc')

{

if (!$this->collected)

return false;

$wheres = $this->GetWhere($where);

if ($where && !$wheres)

return false;

if ($fields && is_array($fields)) { #过滤fields

$val = '';

for ($i = 0; $i 

$val[] = 1;

}

$fields = array_combine($fields, $val);

} else {

$fields = array();

}

$limits = '';

$skip = '';

if (is_string($limit)) { #过滤limit

$limit = explode(",", trim($limit));

if ($limit && is_numeric(implode('', $limit))) {

if (count($limit) == 1) {

$limits = $limit[0];

} else {

$skip = $limit[0];

$limits = $limit[1];

}

}

} elseif (is_numeric($limit)) {

$limits = trim($limit);

}

$sorts = '';

if (is_array($sort) && $sort) { #过滤sort

foreach ($sort as $k => $v) {

$k = trim($k);

$v = strtoupper(trim($v));

if (in_array($v, array_keys($this->sort_map))) {

$sorts[$k] = $this->sort_map[$v];

}

}

}

$result = $this->GetMonCollection($collect)->find($wheres, $fields);

if ($skip)

$result = $result->skip($skip);

if ($limits)

$result = $result->limit($limits);

if ($sorts)

$result = $result->sort($sorts);

if ($result) {

$return = array();

foreach ($result as $v) {

$return[] = $v;

}

foreach ($return as &$v) {

if (in_array('_id', $fields)) {

$arr = get_object_vars($v['_id']);

$v['_id'] = $arr['$id'];

} else {

unset($v['_id']);

}

if (strtolower($type) == 'array')

$v = array_values($v);

}

return $return;

}

return false;

}

/**

* 修改记录

* $inc、$set、$unset 修改普通文档,如果有就修改,没有就条件加值创建,前者只支持数字类型,使用后者,$unset删除元素

* $push、$addToSet 添加数组元素,前者不去重,使用后者

* $pop、$pull 删除数组元素,前者删除前后,后者删除指定元素,使用后者

*

* @param $collect

* @param $where

* @param $newdata |array

* @param string $type   操作类型 upd修改 unset删除指定元素 arr修改数组元素 pull删除数组元素

* @param bool $upsert 是否创建

* @param int $return |1:返回bool,2:返回影响行数

* @return bool

*/

public function UpdMix($collect, $where, $newdata, $type = 'upd', $upsert = false, $return = 1)

{

if (!$this->collected || !is_array($newdata))

return false;

$wheres = $this->GetWhere($where);

if (!$wheres) {

$this->ErrLog('where is error');

return false;

}

$newdata = $this->ConvertEncode($newdata);

$type = strtolower(trim($type));

$types = array('upd' => '$set', 'unset' => '$unset', 'arr' => '$addToSet', 'pull' => '$pull');

if (isset($types[$type])) {

$option = array();

if ($type == 'upd')

$option = array('multiple' => true);

if (in_array($type, array('upd', 'arr')) && $upsert)

$option['upsert'] = true;

$newdata = array($types[$type] => $newdata);

} else {

return false;

}

try {

$result = $this->GetMonCollection($collect)->update($wheres, $newdata, $option);

$result = $return == 1 ? ($result['err'] ? false : true) : $result['n'];

} catch (MongoConnectionException $e) {

$this->ErrLog($e->getMessage());

return false;

}

return $result;

}

#todo EXPLAIN 函数

/**

* 对集合执行命令

* @param $data

* @return bool

*/

public function RunCommand($data)

{

if (is_array($data) && $data && $this->collected) {

$result = $this->db->command($data);

if (isset($result['values']))

return $result['values'];

else

$this->ErrLog("command error,info:" . $result['errmsg'] . ",bad_cmd:" . json_encode($result['bad cmd']));

}

return false;

}

/**

* todo 聚合

*

*/

public function Group()

{

}

public function Count($collect, $where = array())

{

if (!$this->collected)

return false;

$wheres = $this->GetWhere($where);

if ($where && !$wheres)

return false;

return $this->GetMonCollection($collect)->count($wheres);

}

/**

* 返回指定键的唯一值列表

* @param $collect

* @param $key

* @param array $where 额外查询条件

* @return bool

*/

public function Distinct($collect, $key, $where = array())

{

if (!$this->collected)

return false;

$wheres = $this->GetWhere($where);

if ($where && !$wheres)

return false;

try {

$result = $this->GetMonCollection($collect)->distinct($key, $wheres);

} catch (MongoException $e) {

$this->ErrLog($e->getMessage());

return false;

}

return $result;

}

/**

* 删除集合中的记录

* @param $collect

* @param $where

* @param int $return 1:返回bool,2:返回影响行数

* @return bool

*/

public function RemoveColl($collect, $where, $return = 1)

{

if (!$this->collected)

return false;

$wheres = $this->GetWhere($where);

if (!$wheres) {

$this->ErrLog('where is error');

return false;

}

try {

$result = $this->GetMonCollection($collect)->remove($wheres);

$result = $return == 1 ? ($result['err'] ? false : true) : $result['n'];

} catch (MongoConnectionException $e) {

$this->ErrLog($e->getMessage());

return false;

}

return $result;

}

/**

* mongo 错误日志函数

*

* @param $msg

* @param int $lever

*

*/

private function ErrLog($msg, $lever = 2)

{

global $__CFG;

$trace = debug_backtrace();

$error_log = '';

$date = date("Ymd", time());

$line = isset($trace[$lever]['line']) ? trim($trace[$lever]['line']) : '';

$file = isset($trace[$lever]['file']) ? trim($trace[$lever]['file']) : '';

$object = isset($trace[$lever]['object']) ? get_class($trace[$lever]['object']) : '';

$args = isset($trace[$lever]['args']) ? json_encode($trace[$lever]['args']) : '';

$error_log .= "line {$line} " . ($object ? 'of ' . $object : '') . "(in {$file})\n";

$error_log .= $args ? "args:{$args}\n" : '';

$error_log .= "msg:{$msg}";

if (isset($__CFG['com']['id']) && $__CFG['com']['id']) {

$com_id = $__CFG['com']['id'];

} else {

$com_id = 'common';

}

$log_dir = $this->config['logpath'] ? $this->config['logpath'] : __ROOT__ . "data/nginx_error_log/{$com_id}/{$date}/mongo.nginx_error_log";

error_log("Date:" . date("Y-m-d H:i:s", $date) . "\nstamp:{$date}\ntrace:{$error_log}\n\n", 3, $log_dir);

if (isset($__CFG['currUser']) && $__CFG['currUser'] == 'root' && isset($__CFG['daemon']['user'])) {

$paths = explode("nginx_error_log/", $log_dir);

$pathc = explode("/", $paths[1]);

$pathd = $paths[0] . "nginx_error_log";

foreach ($pathc as $v) {

$pathd .= "/" . $v;

chgrp($pathd, $__CFG['daemon']['user']);

chown($pathd, $__CFG['daemon']['user']);

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值