php7性能大幅提高,吸引了很多开发者升级,升级面临的问题很多,mongodb的支持就是其中之一php
php7使用了新的mongdb驱动:git
http://php.net/manual/en/set.mongodb.phpgithub
若是仅仅使用驱动封装的类及方法很是的不方便,因此还必须借助另外一个项目:mongodb
http://php.net/manual/en/mongodb.tutorial.library.phpapi
mongo-php-library对应的文档有:数组
文档: http://mongodb.github.io/mongo-php-library/php7
API: http://mongodb.github.io/mongo-php-library/api/app
mongo-php-library目前的最新版本是1.0.2,这个版本还不支持gridfs的操做。函数
可是从性能
roadmap上已经指出将支持gridfs,可是发布日期没有肯定
Epic
- [PHPLIB-114] - Implement GridFS specification
从Github(https://github.com/mongodb/mongo-php-library)代码上看,/src/GridFS下一直都有更新
仔细阅读了一下代码
为了在发布后能很快实现迁移,我想已经彻底能够进行开发测试了。
通过一番试验,记录一些要点以下:
1.既然是迁移,旧代码对GridFS的调用但愿尽量的不用修改,因此能够封装一个MongoDB\GridFS\Bucket的子类,在子类里封装旧版本GridFS的一些经常使用方法
class MyGridFS extends MongoDB\GridFS\Bucket { //旧驱动有findOne方法,metadata均放在返回对象的file属性以数组方式存放 function findOne($filename) { $ret = new stdClass(); $file = array(); $o=$this->getCollectionWrapper()->findFileByFilenameAndRevision($filename,0); if ($o==NULL) return NULL; $file['md5'] = $o->md5; $file['length'] = $o->length; $file['filename'] = $o->filename; $file['chunkSize'] = $o->chunkSize; $file['_id'] = $o->_id; $file['uploadDate'] = $o->uploadDate; $ret->file = $file; return $ret; } //旧的驱动能够将文件字节字符串直接存入gridfs,新的再也不支持,因此变通先存入一个临时文件,而后再打开临时文件的stream进行写入 //为了提升性能,临时文件所在目录最好为基于内存 function storeBytes($bytes,$metadata) { $filename = $metadata['filename']; if (!$filename) return false; $tmpfile = WORK_TEMP_PATH.md5($filename.time()); file_put_contents($tmpfile,$bytes); $handle = fopen($tmpfile, "r"); $this->uploadFromStream($filename,$handle); @unlink($tmpfile); } function storeFile($filepath,$metadata) { $filename = $metadata['filename']; if (!$filename) return false; $handle = fopen($filepath, "r"); $this->uploadFromStream($filename,$handle); } function getBytes($filename,array $options = []) { $resource = $this->openDownloadStreamByName($filename,$options); return stream_get_contents($resource); } }
2. 实例化grid对象,实际上就是Bucket
$this->grid= new MyGridFS($manage,$dbname,array('bucketName '=>$bucketName));
注意,构造函数第一个参数必须是 MongoDB\Driver\Manager(驱动自带),不能是mongo-php-library带的MongoDB\Client,这有点难以理解,可能考虑了GridFS这部分能从mongo-php-library独立出来吧。
3.findOne里getCollectionWrapper()->findFileByFilenameAndRevision($filename,0); 返回对象里的uploadDate已经再也不是MongoDate,而是 MongoDB\BSON\UTCDateTime,因此要取出上传时的时间戳方法要修改:
$o->file['uploadDate']->sec 修改为 $o->file['uploadDate']->toDateTime()->getTimestamp()
暂时就这么多!