tp已经支持mongodb的数据库,下面是对mongo在tp上的配置和使用做一个详细的说明。
(1)tp3.2.2版本中的/think/model/mongomodel.class.php的原来的类是存在bug的。我们需要在原来的类中添加一些代码,修复bug。
methods,true)) {            // 连贯操作的实现            $this->options[strtolower($method)] =   $args[0];            return $this;        }elseif(strtolower(substr($method,0,5))=='getby') {            // 根据某个字段获取记录            $field   =   parse_name(substr($method,5));            $where[$field] =$args[0];            return $this->where($where)->find();        }elseif(strtolower(substr($method,0,10))=='getfieldby') {            // 根据某个字段获取记录的某个值            $name   =   parse_name(substr($method,10));            $where[$name] =$args[0];            return $this->where($where)->getfield($args[1]);        }else{            e(__class__.':'.$method.l('_method_not_exist_'));            return;        }    }    /**     * 获取字段信息并缓存 主键和自增信息直接配置     * @access public     * @return void     */    public function flush() {        // 缓存不存在则查询数据表信息        $fields =   $this->db->getfields();        if(!$fields) { // 暂时没有数据无法获取字段信息 下次查询            return false;        }        $this->fields   =   array_keys($fields);        foreach ($fields as $key=>$val){            // 记录字段类型            $type[$key]    =   $val['type'];        }        // 记录字段类型信息        if(c('db_fieldtype_check'))   $this->fields['_type'] =  $type;        // 2008-3-7 增加缓存开关控制        if(c('db_fields_cache')){            // 永久缓存数据表信息            $db   =  $this->dbname?$this->dbname:c('db_name');            f('_fields/'.$db.'.'.$this->name,$this->fields);        }    }    // 写入数据前的回调方法 包括新增和更新    protected function _before_write(&$data) {        $pk   =  $this->getpk();        // 根据主键类型处理主键数据        if(isset($data[$pk]) && $this->_idtype == self::type_object) {            $data[$pk] =  new \mongoid($data[$pk]);        }        }    /**     * count统计 配合where连贯操作     * @access public     * @return integer     */    public function count(){        // 分析表达式        $options =  $this->_parseoptions();        return $this->db->count($options);    }    /**     * 获取下一id 用于自动增长型     * @access public     * @param string $pk 字段名 默认为主键     * @return mixed     */    public function getmongonextid($pk=''){        if(empty($pk)) {            $pk   =  $this->getpk();        }        return $this->db->mongo_next_id($pk);    }    /**     * 新增数据     * @access public     * @param mixed $data 数据     * @param array $options 表达式     * @param boolean $replace 是否replace     * @return mixed     */    public function add($data='',$opti {        if(empty($data)) {            // 没有传递数据,获取当前数据对象的值            if(!empty($this->data)) {                $data           =   $this->data;                // 重置数据                $this->data     = array();            }else{                $this->error    = l('_data_type_invalid_');                return false;            }        }        // 分析表达式        $options    =   $this->_parseoptions($options);        // 数据处理        $data       =   $this->_facade($data);        if(false === $this->_before_insert($data,$options)) {            return false;        }        // 写入数据到数据库        $result = $this->db->insert($data,$options,$replace);        if(false !== $result ) {            $this->_after_insert($data,$options);            if(isset($data[$this->getpk()])){                return $data[$this->getpk()];            }        }        return $result;    }    // 插入数据前的回调方法    protected function _before_insert(&$data,$options) {        // 写入数据到数据库        if($this->_autoinc && $this->_idtype== self::type_int) { // 主键自动增长            $pk   =  $this->getpk();            if(!isset($data[$pk])) {                $data[$pk]   =  $this->db->mongo_next_id($pk);            }        }    }    public function clear(){        return $this->db->clear();    }    // 查询成功后的回调方法    protected function _after_select(&$resultset,$options) {        array_walk($resultset,array($this,'checkmongoid'));    }    /**     * 获取mongoid     * @access protected     * @param array $result 返回数据     * @return array     */    protected function checkmongoid(&$result){        if(is_object($result['_id'])) {            $result['_id'] = $result['_id']->__tostring();        }        return $result;    }    // 表达式过滤回调方法    protected function _options_filter(&$options) {        $id = $this->getpk();        if(isset($options['where'][$id]) && is_scalar($options['where'][$id]) && $this->_idtype== self::type_object) {            $options['where'][$id] = new \mongoid($options['where'][$id]);        }    }    /**     * 查询数据     * @access public     * @param mixed $options 表达式参数     * @return mixed     */     public function find($opti {         if( is_numeric($options) || is_string($options)) {            $id   =  $this->getpk();            $where[$id] = $options;            $options = array();            $options['where'] = $where;         }        // 分析表达式        $options =  $this->_parseoptions($options);        $result = $this->db->find($options);        if(false === $result) {            return false;        }        if(empty($result)) {// 查询结果为空            return null;        }else{            $this->checkmongoid($result);        }        $this->data = $result;        $this->_after_find($this->data,$options);        return $this->data;     }    /**     * 字段值增长     * @access public     * @param string $field  字段名     * @param integer $step  增长值     * @return boolean     */    public function setinc($field,$step=1) {        return $this->setfield($field,array('inc',$step));    }    /**     * 字段值减少     * @access public     * @param string $field  字段名     * @param integer $step  减少值     * @return boolean     */    public function setdec($field,$step=1) {        return $this->setfield($field,array('inc','-'.$step));    }    /**     * 获取一条记录的某个字段值     * @access public     * @param string $field  字段名     * @param string $spea  字段数据间隔符号     * @return mixed     */    public function getfield($field,$sepa=null) {        $options['field']    =  $field;        $options =  $this->_parseoptions($options);        if(strpos($field,',')) { // 多字段            if(is_numeric($sepa)) {// 限定数量                $options['limit']   =   $sepa;                $sepa   =   null;// 重置为null 返回数组            }            $resultset = $this->db->select($options);            if(!empty($resultset)) {                $_field = explode(',', $field);                $field  = array_keys($resultset[0]);                $key =  array_shift($field);                $key2 = array_shift($field);         //解决参数$field 指定的字段顺序与数据库中记录字段顺序不一致时导致的返回结果$key不正确问题                //2015-08-15 by bing                if(!(array_search($_field[0], array_keys($resultset[0]))===false)){                    $key=$_field[0];                    $key2=$_field[1];                }                $cols   =   array();                $count  =   count($_field);                foreach ($resultset as $result){                    $name   =  $result[$key];                    if(2==$count) {                        $cols[$name]   =  $result[$key2];                    }else{                        $cols[$name]   =  is_null($sepa)?$result:implode($sepa,$result);                    }                }                return $cols;            }        }else{            // 返回数据个数            if(true !== $sepa) {// 当sepa指定为true的时候 返回所有数据                $options['limit']   =   is_numeric($sepa)?$sepa:1;            }            // 查找一条记录            $result = $this->db->select($options);            if(!empty($result)) {                foreach ($result as $val){                    if(strpos($field,'.')){                        $tmp=explode('.', $field);                        foreach ($tmp as $t){                            $val=$val[$t];                        }                        $array[]    =   $val;                    }else{                        $array[]    =   $val[$field];                    }                }                return 1 == $options['limit'] ? $array[0] : $array;            }        }        return null;    }    /**     * 执行mongo指令     * @access public     * @param array $command  指令     * @return mixed     */    public function command($command) {        return $this->db->command($command);    }    /**     * 执行mongocode     * @access public     * @param string $code  mongocode     * @param array $args   参数     * @return mixed     */    public function mongocode($code,$args=array()) {        return $this->db->execute($code,$args);    }    // 数据库切换后回调方法    protected function _after_db() {        // 切换collection       //bing 2015-8-15 获取数据表     if(empty($this->dbname) && !empty($this->connection)){            $db_c            $this->dbname=$db_config['db_name'];        }        $this->db->switchcollection($this->gettablename(),$this->dbname);      }    /**     * 得到完整的数据表名 mongo表名不带dbname     * @access public     * @return string     */    public function gettablename() {        if(empty($this->truetablename)) {            $tablename  = !empty($this->tableprefix) ? $this->tableprefix : '';            if(!empty($this->tablename)) {                $tablename .= $this->tablename;            }else{                $tablename .= parse_name($this->name);            }            $this->truetablename    =   strtolower($tablename);        }        return $this->truetablename;    }}  
上面是一个修改之后的完整的mongo类。其中
(1)
protected $connection       =   'db_mongo'; 是链接配置config对应的db_mongo(2)
//解决参数$field 指定的字段顺序与数据库中记录字段顺序不一致时导致的返回结果$key不正确问题                //2015-08-15 by bing                if(!(array_search($_field[0], array_keys($resultset[0]))===false)){                    $key=$_field[0];                    $key2=$_field[1];                }
这一块是添加进去的,建立数据库的缓存(3)
//bing 2015-8-15 获取数据表     if(empty($this->dbname) && !empty($this->connection)){            $db_c            $this->dbname=$db_config['db_name'];        }        $this->db->switchcollection($this->gettablename(),$this->dbname);   
这一个函数在tp原来的mongomodel里只会默认链接到mysql的配置dbname中去,现要作修改,如上所示。二、在tp中配置db_mongo
(1)在config文件 中添加
'db_mongo'=>		array(			'db_type'   => 'mongo', // 数据库类型			'db_host'   => 'localhost', // 服务器地址			'db_name'   => 'test', // 数据库名			'db_user'   => '', // 用户名			'db_pwd'    => '', // 密码			'db_port'   => '27017', // 端口 	),
mongo默认是没有认证的,所以用户名和密码为空。(2)在mongomodel的添加
protected $connection       =   'db_mongo'; 是链接配置config对应的db_mongo,就是上面的完整的mongo类。
至此数据库的配置已经完成。三、安装php_mongo驱动
在windows上安装驱动必须要和自己所用的php大版本想对应。
(1)下载对应版本的php_mongo。
(2)将php_mongo.dll复制到php的ext文件中
(3)在php.ini中添加extension=php_mongo.dll
(4)重启apache
(5)访问phpinfo,搜索mongo
出现上面代表配置成功。
四、tp上mongo的curd操作
(1)php连接mongo,创建实例化对象
$m=new \think\model\mongomodel('user');
其中“user”是集合,相当于mysql中的表。
(2)添加——add()
查询和mysql基本一样,
example:
$data=array(          name=>李四,          addr=>深圳,          sex=>男,          info=>array(              age=>20,              phone=>12345,            ),        );
$result=$m->add($data);这样就将数据添加作为一个文档,相当于mysql的一条记录。
(2)查询——select(),getfield()
如果要查询刚才插进去的$data
$map['name']=李四,
$result=$m->where($map)->select();
查找的是整个文档,返回的是一个数组。如图
array(5) {    [_id] => int(4)    [name] => string(6) 李四    [addr] => string(6) 深圳    [sex] => string(3) 男    [info] => array(2) {      [age] => int(20)      [phone] => string(5) 12345    }  }
如果要查一个字段,可以用getfield();$result=$m->where($map)->getfield('info');
查出来如图
array(2) {  [age] => int(20)  [phone] => string(5) 12345}
如果要查age这个键的值,直接 $result=$m->where($map)->getfield('info.age');
返回int(20)
时间区段的查询,要用数组形式查询
比如文档中有一个键“time”,要查找2015/815-2015/9/1之间的文档。
$map=array('time'=>array('$gt'=>int,'$lt'=>int))
$result=$m->where($map)->select()
其中int代表时间戳。(3)删除——delete();
$result=$m->where($map)->delete();
这个delete的删除是删除整个文档。(4)修改——save()
set
例如重新修改文档中的sex=>‘男’,改为sex=>'女
$update['sex']=array('set','女'); $m->where($map)->save($update);
结果:array(5) {    [_id] => int(4)    [name] => string(6) 李四    [addr] => string(6) 深圳    [sex] => string(3) 女    [info] => array(2) {      [age] => int(20)      [phone] => string(5) 12345    }
例如修改内嵌文档中的某个键的值,比如age$update['info.age']=array('set',30);$m->where($map)->save($update);
结果: array(5) {    [_id] => int(3)    [name] => string(6) 李四    [addr] => string(6) 深圳    [sex] => string(3) 女    [info] => array(2) {      [age] => int(30)      [phone] => string(5) 12345    }  }
unset比如要删除某个键。
例如删除文档中的addr键
$update['addr']=array('unset');  $m->where($map)->save($update);
结果:
array(4) {    [_id] => int(3)    [name] => string(6) 李四    [sex] => string(3) 女    [info] => array(2) {      [age] => int(30)      [phone] => string(5) 12345    }  }
可以看到已经没有addr键了push——追加一个值到字段(必须是数组类型)里面去
比如一个数组(这里不包括关系型数组)
$data=array(          name=>李四,          addr=>深圳,          sex=>男,          info=>array(              age=>20,              phone=>12345,            ),          num=>array();        );   $result=$m->add($data);
num是一个数组,向里面修改添加数据。
$update['num']=array('push',1);$m->where($map)->save($update);
结果:
array(5) {    [_id] => int(3)    [name] => string(6) 李四    [sex] => string(3) 女    [info] => array(2) {      [age] => int(30)      [phone] => string(5) 12345    }   [num] => array(1) {      [0] => int(1)    }  }
如果要添加数组
$update['num']=array('push',array('subject'=>'php'));      $m->where($map)->save($update);
结果:
array(5) {    [_id] => int(3)    [name] => string(6) 李四    [sex] => string(3) 女    [info] => array(2) {      [age] => int(30)      [phone] => string(5) 12345    }    [num] => array(2) {      [0] => int(1)      [1] => array(1) {        [subject] => string(3) php      }    }  }
pull——根据值删除字段(必须是数组字段)中的一个值现在要删除刚才添加在num数组里的array('suject'=>'php')
$update['num']=array('pull',array('subject'=>'php')); $m->where($map)->save($update);
结果:array(5) {    [_id] => int(3)    [name] => string(6) 李四    [sex] => string(3) 女    [info] => array(2) {      [age] => int(30)      [phone] => string(5) 12345    }    [num] => array(1) {      [0] => int(1)    }  }
可以看到num数组里已经没有array('suject'=>'php');(5)统计——count()
$result=$m->where($map)->count();
至此,以上方法都是经过实践测试的,mongo最常用的,能满足业务要求的方法总结结束。如有什么不对的地方,请指出!
版权声明:本文为博主原创文章,未经博主允许不得转载。
                                                                    以上就介绍了tp上mongo的配置,包括了方面的内容,希望对php教程有兴趣的朋友有所帮助。
   
 
   