邢栋博客

邢栋博客,Action博客,记录工作和生活中的点点滴滴

thinkphp3.2同时支持mysql和mongodb

1.如果只是支持mysql,就不用说了,先说说只支持mongodb吧

在config.php中

<?php
return array(
//'配置项'=>'配置值'
'DB_TYPE'=>'mongo',
'DB_HOST'=> '127.0.0.1', 
'DB_USER'=>'',      
'DB_PWD'=>'',        
'DB_PORT'=>'27017',
'DB_NAME'=> 'test',     
 'DB_PREFIX'=> '',

);

新建一个TestModel.class.php文件

<?php
namespace Home\Model;
use Think\Model\MongoModel;
Class TestModel extends MongoModel{

}
?>

然后在控制器中 

$user =  D("users")->select();

var_dump($user);

就可以了。


2.同时支持mysql和mongodb

测试后发现只能以mogodb为主是可以使用的。

在config.php配置文件中

<?php
return array(
//'配置项'=>'配置值'
'DB_TYPE'=>'mongo',
'DB_HOST'=> '127.0.0.1', 
'DB_USER'=>'',      
'DB_PWD'=>'',        
'DB_PORT'=>'27017',
'DB_NAME'=> 'test',     
 'DB_PREFIX'=> '',

'DB_MYSQL' => array(
'DB_TYPE' => 'mysql', // 数据库类型
'DB_HOST' => 'localhost', // 服务器地址
'DB_NAME' => 'test, // 数据库名
'DB_USER' => 'root', // 用户名
'DB_PWD' => '1314', // 密码
'DB_PORT' => 3306, // 端口
'DB_PREFIX' => 'action_' // 数据库表前缀
),

);


然后mongodb的调用方法不变,mysql调用方法

mysql的可以这样:
$user = M('user','action_','DB_MYSQL')->select();
var_dump($user):


手册介绍地址:http://document.thinkphp.cn/manual_3_2.html#connect_db

mongo的基本操作(包括php的)

db.test.find()<==> select *from test
db.test.find({'name':'foobar'})<==> select * from test where name='foobar'
db.test.find({'ID':10}).count()<==> select count(*) from test where ID=10
db.test.find().skip(10).limit(20)<==> select * from test limit 10,20
db.test.find({'ID':{$in:[25,35,45]}})<==> select * from test where ID in (25,35,45)
db.test.find().sort({'ID':-1})  <==> select * from test order by ID desc
db.test.distinct('name',{'ID':{$lt:20}})  <==> select distinct(name) from testwhere ID<20
db.test.group({key:{'name':true},cond:{'name':'foo'},reduce:function(obj,prev){prev.msum+=obj.marks;},initial:{msum:0}})  <==> select name,sum(marks) from testgroup by name
db.test.find('this.ID<20',{name:1})  <==> select name from test where ID<20
<?php
$m = new MongoClient();
$db = $m->selectDB('test');
$collection = new MongoCollection($db, 'produce');
// search for fruits
$fruitQuery = array('Type' => 'Fruit');
$cursor = $collection->find($fruitQuery);//
// search for documents where 5 < x < 20
$rangeQuery = array('x' => array( '$gt' => 5, '$lt' => 20 ));
$cursor = $collection->find($rangeQuery);
//
$js = "function() {
return this.name == 'Joe' || this.age == 50;
}";
$cursor = $collection->find(array('$where' => $js))
//where name in ()
$cursor = $collection->find(array(
'name' => array('$in' => array('Joe', 'Wendy'))
));
?>

db.test.insert({'name':'foobar','age':25})<==>insert into test ('name','age') values('foobar',25)
<?php
$collection->insert(array('x' => 1));
?>

db.test.remove({})<==> delete * from test
db.test.remove({'age':20})<==>delete test where age=20
db.test.remove({'age':{$lt:20}})<==> delete test where age<20
db.test.remove({'age':{$lte:20}})<==> delete test where age<=20
db.test.remove({'age':{$gt:20}})<==> delete test where age>20
db.test.remove({'age':{$gte:20}})<==> delete test where age>=20
db.test.remove({'age':{$ne:20}})<==> delete test where age!=20
<?php
$radioactive->remove(array('type' => 94), array("justOne" => true));
?>

db.test.update({'name':'foobar'},{$set:{'age':36}})<==> update test set age=36 where name='foobar'
db.test.update({'name':'foobar'},{$inc:{'age':3}})<==> update test set age = age+3 where name='foobar'
<?php
$newdata = array('$set' => array("address" => "1 Smith Lane"));
$c->update(array("firstname" => "Bob"), $newdata);
?>

db.imooc_collection.update({x:1},{x:999}) //把x=1的改成x=999的,只更新一条
db.imooc_collection.update({x:1},{$set:{y:100}}) //单个字段更新
db.imooc_collection.update({x:999},{x:777},true) //更新数据,如果不存在,创建
db.imooc_collection.update({x:999},{$set{x:777}},false,true) 更新多条
db.imooc_collection.remove({x:777}) //删除x=777
db.imooc_collection.drop() //删除表imooc_collection
db.imooc_collection.getIndexes() //查询索引
db.imooc_collection.ensureIndex({x:1}) //增加索引

windows下装php的mongodb扩展

windows下装php的mongodb扩展,遇到一个问题 ,折腾了半天

问题:phpinfo中看不到mongo的信息,扩展都已经配置进去,apache重启也没有报错

我的电脑环境是装的wampserver,php版本是5.5.12,X64,我先下载mongodb的安装包mongodb-win32-x86_64-2008plus-ssl-3.0.3-signed.msi(官网可下载到),如日志http://xingdong365.com/network/32.html 已经正常了。

下面需要装扩展文件,找的是对应的版本 php_mongo-1.6.8-5.5-vc11-x86_64.dll (地址:http://windows.php.net/downloads/pecl/releases/mongo/1.6.8/)。复制到php的ext目录下,又更改php.ini,wampserver环境也已经在扩展php_mongo 打上了对钩。感觉没啥问题。可就是在访问phpinfo.php的时候没有mongo的信息。

折腾的半天,最后找了一个php_mongo-1.4.5-5.5-vc11-x86_64.dll(地址:http://download.csdn.net/download/dupingjin/7577217),终于解决了。看来还是版本问题。


php常用魔术方法
 //__construct 
  //构造函数 在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法。如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct() 。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)。 
  class Animal{
    public function __construct() {
    $this->created = time();
    $this->logfile_handle = fopen('/tmp/log.txt', 'w');
    }
  }

  class Penguin extends Animal {
  }
  $tux = new Penguin;
  echo $tux->created;

  //__destruct 
  //析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。
  //和构造函数一样,父类的析构函数不会被引擎暗中调用。要执行父类的析构函数,必须在子类的析构函数体中显式调用 parent::__destruct() 。此外也和构造函数一样,子类如果自己没有定义析构函数则会继承父类的。 
  //析构函数即使在使用 exit()  终止脚本运行时也会被调用。在析构函数中调用 exit()  将会中止其余关闭操作的运行。
  class Animal{
    public function __construct() {
      $this->created = time();
      $this->logfile_handle = fopen('/tmp/log.txt', 'w');
    }
    public function __destruct() {
      fclose($this->logfile_handle);
    }
  }

  //__get
  //读取不可访问属性的值时,__get() 会被调用。 
  //__set
  //在给不可访问属性赋值时,__set() 会被调用。 
 class  PropertyTest  {
    /**  被重载的数据保存在此  */
    private  $data  = array();
    /**  重载不能被用在已经定义的属性  */
    public  $declared  =  1 ;
    /**  只有从类外部访问这个属性时,重载才会发生 */
    private  $hidden  =  2 ;
    public function  __set ( $name ,  $value ){
        echo  "Setting ' $name ' to ' $value '\n" ;
        $this -> data [ $name ] =  $value ;
    }
    public function  __get ( $name ) {
      echo  "Getting ' $name '\n" ;
      if ( array_key_exists ( $name ,  $this -> data )) {
        return  $this -> data [ $name ];
      }
      $trace  =  debug_backtrace ();
        trigger_error (
             'Undefined property via __get(): '  .  $name  .
             ' in '  .  $trace [ 0 ][ 'file' ] .
             ' on line '  .  $trace [ 0 ][ 'line' ],
             E_USER_NOTICE );
        return  null ;
    }
  }
  $obj  = new  PropertyTest ;
  $obj -> a  =  1 ;
  echo  $obj -> a  .  "\n\n" ;

  //__call
  //在对象中调用一个不可访问方法时,__call() 会被调用。 
  //用静态方式中调用一个不可访问方法时,__callStatic() 会被调用。 

  class  MethodTest {
    public function  __call ( $name ,  $arguments ) {
      // 注意: $name 的值区分大小写
      echo  "Calling object method ' $name ' ".  implode ( ', ' ,  $arguments ).  "\n" ;
    }
     /**  PHP 5.3.0之后版本  */
    public static function  __callStatic ( $name ,  $arguments ) {
      // 注意: $name 的值区分大小写
      echo  "Calling static method ' $name ' ".  implode ( ', ' ,  $arguments ).  "\n" ;
    }
  }
  $obj  = new  MethodTest ;
  $obj -> runTest ( 'in object context' );
  MethodTest :: runTest ( 'in static context' );   // PHP 5.3.0之后版本



  //__sleep
  //__sleep()方法会被调用当对象被序列化后,并允许你处理序列化。这有各种各样的程序,一个很好的例子如果一个对象包含某种类型的指针,例如文件句柄或引用另一个对象。当对象被序列化然后解序列化,这些引用类型是无用的,因为这些类型的引用的目标可能不再存在或有效。因此,最好是来取消这些信息在存储它们之前。

  //__wakeup
  //wakeup()是与__sleep()方法相反的,允许您更改对象解序列化的行为。和__sleep()一起使用,可以用来恢复被删除的句柄和对象当对象被序列化时。一个很好的例子程序是数据库句柄被取消设置当该项被序列化,然后恢复到当前配置中设置项目时,解序列化一个数据库句柄。

  //__clone
  //我们看过一个使用clone关键字的例子,在我的介绍从入门到oop的第二部分,创建对象的副本,而不是有两个变量指向同一个实际的数据。在一个类中重写此方法,我们可以观察发生了什么当在对象上使用clone关键字时,。虽然这是不是我们每一天能遇到的,一个漂亮的用例是创建一个真正的单例模式通过添加private访问修饰符给这个方法。

  //__toString
  //__toString() 方法用于一个类被当成字符串时应怎样回应。例如 echo $obj; 应该显示些什么。此方法必须返回一个字符串,否则将发出一条 E_RECOVERABLE_ERROR  级别的致命错误。 
  // Declare a simple class
  class  TestClass{
    public  $foo ;
    public function  __construct ($foo) {
      $this -> foo  =  $foo ;
    }
    public function  __toString () {
      return  $this -> foo ;
    }
  }

  $class  = new  TestClass ( 'Hello' );
  echo  $class ;


ps:参考地址:

http://php.net/manual/zh/language.oop5.magic.php

http://www.oschina.net/translate/9-magic-methods-in-php?print

php屏蔽手机号和固话的中间四位
<?php 
	
	//php屏蔽手机号和固话的中间四位

	//php屏蔽手机号码的中间四位
	//方法1 利用正则
	$phone = 13811119999;
	echo preg_replace('/(1[3|4|5|6|7|8|9][0-9])[0-9]{4}([0-9]{4})/i','$1****$2',$phone);
	echo "<br>";
	//方法2 
	echo substr_replace($phone,'****',3,4);
	echo "<br>";

	//ps屏蔽固话中间四位
	$tel1 = "0632-2396517";
	$tel2 = "0632-2396517-083";
	echo preg_replace('/(0[0-9]{2,3}[\-]?[2-9])[0-9]{3,4}([0-9]{3}[\-]?[0-9]?)/i','$1****$2',$tel1);
	echo "<br>";
	echo preg_replace('/(0[0-9]{2,3}[\-]?[2-9])[0-9]{3,4}([0-9]{3}[\-]?[0-9]?)/i','$1****$2',$tel2);



?>
php标准库spl的文件处理函数
SplFileInfo用于获得文件的基本信息,比如修改时间、大小、目录等信息

SplFileObject用户操作文件的内容,比如读取、写入

<?php
header("Content-type:text/html;charset=utf-8");
date_default_timezone_set('PRC');
$file = new SplFileInfo('studynote/imooc.txt');
echo "文件创建时间:".date('Y-m-d H:i:s',$file->getCTime())."<br>";
echo "文件最后修改时间:".date('Y-m-d H:i:s',$file->getMTime())."<br>";
echo "文件大小:".$file->getSize()."字节<br>";
//读取文件内容
$fileObj = $file->openFile('r');
while($fileObj->valid()){
echo $fileObj->fgets();//fgets函数获取文件里面的一行数据
}
$fileObj = null;//用户关闭打开的文件
$file = null;

?>

php标准库spl函数的使用(Autoload)
为了初始化php中的类对象,需要通过一定的方法寻找到类的定义。通常情况下,类会定义在一个单独的文件中。
Autoload就是php找到这类文件的方法。
spl函数的使用->类载入基本流程
开始->当前文件找类->找到->初始化类
开始->当前文件找类->未找到->依次调用spl_autoload_register注册的方法找类->找到->初始化类
开始->当前文件找类->未找到->依次调用spl_autoload_register注册的方法找类->未找到->文件的__autoload函数找类
//类文件放在lib文件夹下test.php,test.class.php
1.autoload01.php 
<?php
define('CLASS_DIR', 'lib/');
set_include_path(get_include_path().PATH_SEPARATOR.CLASS_DIR);//设置autoload寻找php定义的类文件的目录,多个目录用PATH_SEPARATOR进行分隔
//spl_autoload_extensions('.class.php');//
spl_autoload_extensions('.class.php,.php');//设置autoload寻找php定义的类文件的扩展名,多个扩展名用逗号分隔,前面的扩展名优先被匹配
spl_autoload_register();//提示php使用autoload机制进行查找自定义
$obj = new Test();
?>
2.autoload02.php
<?php
function __autoload($class_name){//定义__autoload函数,可以在不调用spl_autoload_register函数的情况下完成类的装载
echo "__autoload class:".$class_name."<br>";
//require_once("lib/".$class_name.".php");
require_once("lib/".$class_name.".class.php");//装载类
}
//定义一个替换__autoload函数的类文件装载函数
function classloader($class_name){
echo "classloader() load class: ".$class_name."<br>";
require_once("lib/".$class_name.".php");//装载类
}
spl_autoload_register('classloader');//传入定义好的装载类的函数的名称替换__autoload函数
$obj = new Test();
?>
3.autoload03.php 
<?php
//定义一个替换__autoload函数的类文件装载函数
function classloader($class_name){
echo "classloader() load class: ".$class_name."<br>";
set_include_path('lib/');
spl_autoload($class_name);//当我们不用require或者require_once载入类文件的时候,而想通过系统查找include_path来装载类时,必须显示调用sp_autoload函数,参数是类的名称来重启类文件自动查找(装载)
}
spl_autoload_register('classloader');//传入定义好的装载类的函数的名称替换__autoload函数

$obj = new Test();

?>
php标准库spl的常用接口
spl的基础接口里面定义了最常用的接口
Countable 继承了该接口的类可以直接调用count()得到元素个数
<?php
date_default_timezone_set('PRC');
//继承了implements Countable接口,实现了count()方法  就可以使用count($obj)进行计算
class CountMe implements Countable{
protected $_mycount = 3;
public function count(){
return $this->_mycount;
}
}
$obj = new CountMe();
echo count($obj);
?>
OuterIterator OuterIterator 如果想对迭代器进行一定的处理之后再返回,可以用这个接口
IteratorIterator类是OuterIterator的实现,扩展的时候可以直接继承IteratorItreator
<?php
date_default_timezone_set('PRC');
$array = ["value1","value2","value3","value4"];
$outerObj = new OuterImpl(new ArrayIterator($array));

foreach ($outerObj as $key => $value) {
echo "++".$key."--".$value."<br>";
}

class OuterImpl extends IteratorIterator{
public function current(){
return parent::current()."_tail";

}

public function key(){
return "Pre_".parent::key();
}
}
?>

RecursiverIterator 可以对多层结构的迭代器进行迭代,比如遍历一棵树
所有具有层次结构特点的数据都可以用这个接口遍历,如文件夹
关键方法:
hasChildren方法用于判断当前节点是否存在子节点
getChildren方法用于得到当前节点子节点的迭代器
spl中实现该接口的类
RecursiveArrayIterator、RecursiveCachingIterator等以Recursive开头的类都能够进行多层次结构化的遍历

<?php

class MyRecursiveIterator implements RecursiveIterator
{
    private $_data;
    private $_position = 0;
    
    public function __construct(array $data) {
        $this->_data = $data;
    }
    
    public function valid() {
        return isset($this->_data[$this->_position]);
    }
    
    public function hasChildren() {
        return is_array($this->_data[$this->_position]);
    }
    
    public function next() {
        $this->_position++;
    }
    
    public function current() {
        return $this->_data[$this->_position];
    }
    
    public function getChildren() {
        echo '<pre>';
        print_r($this->_data[$this->_position]);
        echo '</pre>';
    }
    
    public function rewind() {
        $this->_position = 0;
    }
    
    public function key() {
        return $this->_position;
    }
}

$arr = array(0, 1, 2, 3, 4, 5 => array(10, 20, 30), 6, 7, 8, 9 => array(1, 2, 3));
$mri = new MyRecursiveIterator($arr);

foreach ($mri as $c => $v) {
    if ($mri->hasChildren()) {
        echo "$c has children: <br />";
        $mri->getChildren();
    } else {
        echo "$v <br />";
    }

}
?>


SeekableItertator 可以通过seek方法定位集合里面的某个特定元素
可以通过seek方法定位到集合里面的某个特定元素
seek方法的参数是元素的位置,从0开始计算
spl实现该接口的类
ArrayIterator、DirectoryIterator、FilesystemIterator、GlobIterator、RecursiveArrayIterator、RecursiveDirectoryIterator

优惠券
广告位-淘宝
最新微语