兔兔兔 發表於 2019-10-25 11:46:00

mongodb实现文件存储系统

<p>前言:这种坑很深呀,要对应mongodb的版本跟php支持的版本,然后,如果要用composer安装第三方的库,一定要一一对应的</p>
<p>&nbsp;<img src="https://img2018.cnblogs.com/blog/1740309/201910/1740309-20191025114136732-1492005417.png"></p>
<p>&nbsp;<img src="https://img2018.cnblogs.com/blog/1740309/201910/1740309-20191025114140085-1568825516.png"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-size: 14pt"><strong>正片开始!</strong></span></p>
<p>&nbsp;</p>
<p>开发环境:</p>
<p>系统:window</p>
<p>开发语言:php+apache+tp5</p>
<p>&nbsp;</p>
<p>一、window下安装mongodb:http://baijiahao.baidu.com/s?id=1601512248926547477&amp;wfr=spider&amp;for=pc</p>
<p>二、通过composer下载第三方库(封装一个类)</p>
<p>mongosStorage.php</p>
<div class="cnblogs_code">
<pre>&lt;?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
* Created by PhpStorm.
* User: gan
* Date: 2019/10/22
* Time: 14:58
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
namespace app\common\lib; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 命名空间</span>
<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> mongosStorage{

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 1、必须定义一个静态私有属性
    // 2、定义一个私有构造方法
    // 3、单例模式就是为了避免多次new同一个对象,形成统一路口</span>
    <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(128, 0, 128, 1)">$obj</span> = <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(128, 0, 128, 1)">$collection</span> = <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> __construct()
    {
      </span><span style="color: rgba(128, 0, 128, 1)">$this</span>-&gt;collection = (<span style="color: rgba(0, 0, 255, 1)">new</span> \MongoDB\Client)-&gt;storage-&gt;<span style="color: rgba(0, 0, 0, 1)">selectGridFSBucket();
    }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> singleEntrance(){
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 判断对象是否已经实例化过</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span>(!self::<span style="color: rgba(128, 0, 128, 1)">$obj</span><span style="color: rgba(0, 0, 0, 1)"> instanceof self){
            self</span>::<span style="color: rgba(128, 0, 128, 1)">$obj</span> = <span style="color: rgba(0, 0, 255, 1)">new</span> self(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 如果没有就要实例化一下</span>
<span style="color: rgba(0, 0, 0, 1)">      }
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> self::<span style="color: rgba(128, 0, 128, 1)">$obj</span><span style="color: rgba(0, 0, 0, 1)">;
    }

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 防止外部克隆</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> __clone()
    {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO: Implement __clone() method.</span>
<span style="color: rgba(0, 0, 0, 1)">    }

    </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
   * @param $filename(仅仅是文件名,不需要路径)
   * @param $filepath(绝对路径的文件)
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span> deposit(<span style="color: rgba(128, 0, 128, 1)">$filename</span>,<span style="color: rgba(128, 0, 128, 1)">$filepath</span><span style="color: rgba(0, 0, 0, 1)">){
      </span><span style="color: rgba(128, 0, 128, 1)">$stream</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>-&gt;collection-&gt;openUploadStream(<span style="color: rgba(128, 0, 128, 1)">$filename</span><span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(128, 0, 128, 1)">$contents</span> = <span style="color: rgba(0, 128, 128, 1)">file_get_contents</span>(<span style="color: rgba(128, 0, 128, 1)">$filepath</span><span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(0, 128, 128, 1)">fwrite</span>(<span style="color: rgba(128, 0, 128, 1)">$stream</span>, <span style="color: rgba(128, 0, 128, 1)">$contents</span><span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(0, 128, 128, 1)">fclose</span>(<span style="color: rgba(128, 0, 128, 1)">$stream</span><span style="color: rgba(0, 0, 0, 1)">);
    }

    </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
   * 获取文件ID
   * @param $filename (仅仅是文件名,不需要路径)
   * @return mixed
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span> getFileId(<span style="color: rgba(128, 0, 128, 1)">$filename</span> = ''<span style="color: rgba(0, 0, 0, 1)">){
      </span><span style="color: rgba(128, 0, 128, 1)">$stream</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>-&gt;collection-&gt;openDownloadStreamByName(<span style="color: rgba(128, 0, 128, 1)">$filename</span><span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(128, 0, 128, 1)">$fileId</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>-&gt;collection-&gt;getFileIdForStream(<span style="color: rgba(128, 0, 128, 1)">$stream</span><span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">$fileId</span><span style="color: rgba(0, 0, 0, 1)">;
    }


    </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
   * 取
   * @param $filename (仅仅是文件名,不需要路径)
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span> take(<span style="color: rgba(128, 0, 128, 1)">$filename</span> = ''<span style="color: rgba(0, 0, 0, 1)">){
      </span><span style="color: rgba(128, 0, 128, 1)">$stream</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>-&gt;collection-&gt;openDownloadStreamByName(<span style="color: rgba(128, 0, 128, 1)">$filename</span>, ['revision' =&gt; 0<span style="color: rgba(0, 0, 0, 1)">]);
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 128, 128, 1)">stream_get_contents</span>(<span style="color: rgba(128, 0, 128, 1)">$stream</span><span style="color: rgba(0, 0, 0, 1)">);
    }

}</span></pre>
</div>
<p>&nbsp;</p>
<p>二、显示在html上</p>
<p>&nbsp;<img src="https://img2018.cnblogs.com/blog/1740309/201910/1740309-20191025114308612-1594071409.png"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="color: rgba(255, 0, 0, 1); font-size: 12px">*由于我存入的时候,没有保存内容类型,所以,取的时候有点麻烦*</span></p>
<p><span style="color: rgba(255, 0, 0, 1); font-size: 12px">取出二进制图片后,通过php生成图片,html请求显示图片</span></p>
<p>&nbsp;</p>
<p><span style="font-size: 14px; color: rgba(0, 0, 0, 1)">图片操作控制器文件代码</span></p>
<div class="cnblogs_code">
<pre>&lt;?<span style="color: rgba(0, 0, 0, 1)">php

</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
* FLY rms 图片操作控制器
* @author fly
* 2018-9-30 15:52:21
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">

namespace app\admin\controller;
</span><span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> app\common\lib\mongosStorage;
</span><span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> think\Controller;
</span><span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> think\Request;

</span><span style="color: rgba(0, 0, 255, 1)">class</span> Image <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> Admin
{

   
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">上传功能</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> upload(){
      
      </span><span style="color: rgba(128, 0, 128, 1)">$return</span> = <span style="color: rgba(0, 0, 255, 1)">array</span><span style="color: rgba(0, 0, 0, 1)">(
                </span>'msg'=&gt;'fall',
                'code'=&gt;201,
                'mongodb_id'=&gt;'',
                'filename'=&gt;'',<span style="color: rgba(0, 0, 0, 1)">
      );
      
      </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {


            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 移动到框架应用根目录/public/uploads/ 目录下</span>
            <span style="color: rgba(128, 0, 128, 1)">$file</span> = request()-&gt;<span style="color: rgba(0, 128, 128, 1)">file</span>('image'<span style="color: rgba(0, 0, 0, 1)">);
            </span><span style="color: rgba(128, 0, 128, 1)">$file_name</span> = ''<span style="color: rgba(0, 0, 0, 1)">;
            </span><span style="color: rgba(128, 0, 128, 1)">$mongodb_id</span> = ''<span style="color: rgba(0, 0, 0, 1)">;
            </span><span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(128, 0, 128, 1)">$file</span><span style="color: rgba(0, 0, 0, 1)">){

                </span><span style="color: rgba(128, 0, 128, 1)">$root_path</span> = __DIR__."/../../../public/uploads/temporaryFile/"<span style="color: rgba(0, 0, 0, 1)">;

                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">不同模块保存不同的文件</span>
                <span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 128, 128, 1)">is_dir</span>(<span style="color: rgba(128, 0, 128, 1)">$root_path</span><span style="color: rgba(0, 0, 0, 1)">)) {
                   </span><span style="color: rgba(0, 128, 128, 1)">mkdir</span>(<span style="color: rgba(128, 0, 128, 1)">$root_path</span>,0777,<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">);
                }
                </span><span style="color: rgba(128, 0, 128, 1)">$savename</span> = <span style="color: rgba(0, 128, 128, 1)">date</span>('YmdHis') . <span style="color: rgba(0, 128, 128, 1)">rand</span>(10000, 99999<span style="color: rgba(0, 0, 0, 1)">);
                </span><span style="color: rgba(128, 0, 128, 1)">$info</span> = <span style="color: rgba(128, 0, 128, 1)">$file</span>-&gt;move(<span style="color: rgba(128, 0, 128, 1)">$root_path</span>,<span style="color: rgba(128, 0, 128, 1)">$savename</span><span style="color: rgba(0, 0, 0, 1)">);
                </span><span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(128, 0, 128, 1)">$info</span><span style="color: rgba(0, 0, 0, 1)">){
                  </span><span style="color: rgba(128, 0, 128, 1)">$file_name</span> = <span style="color: rgba(128, 0, 128, 1)">$info</span>-&gt;<span style="color: rgba(0, 0, 0, 1)">getFilename();
                  </span><span style="color: rgba(128, 0, 128, 1)">$obj</span> = mongosStorage::<span style="color: rgba(0, 0, 0, 1)">singleEntrance();
                  </span><span style="color: rgba(128, 0, 128, 1)">$obj</span>-&gt;deposit(<span style="color: rgba(128, 0, 128, 1)">$file_name</span>,<span style="color: rgba(128, 0, 128, 1)">$root_path</span>.<span style="color: rgba(128, 0, 128, 1)">$file_name</span><span style="color: rgba(0, 0, 0, 1)">);
                  </span><span style="color: rgba(128, 0, 128, 1)">$mongodb_id</span> = <span style="color: rgba(128, 0, 128, 1)">$obj</span>-&gt;getFileId(<span style="color: rgba(128, 0, 128, 1)">$file_name</span><span style="color: rgba(0, 0, 0, 1)">);
                  </span><span style="color: rgba(0, 0, 255, 1)">unset</span>(<span style="color: rgba(128, 0, 128, 1)">$info</span>); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 网上查是tp5才会这样</span>
                  @<span style="color: rgba(0, 128, 128, 1)">unlink</span>(<span style="color: rgba(128, 0, 128, 1)">$root_path</span>.<span style="color: rgba(128, 0, 128, 1)">$file_name</span>); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 删除临时文件</span>
                }<span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
                  </span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span> \<span style="color: rgba(0, 0, 255, 1)">Exception</span>(<span style="color: rgba(128, 0, 128, 1)">$file</span>-&gt;<span style="color: rgba(0, 0, 0, 1)">getError());
                }
            }
      
            </span><span style="color: rgba(128, 0, 128, 1)">$return</span>['code'] = 200<span style="color: rgba(0, 0, 0, 1)">;
            </span><span style="color: rgba(128, 0, 128, 1)">$return</span>['msg'] = "success"<span style="color: rgba(0, 0, 0, 1)">;
            </span><span style="color: rgba(128, 0, 128, 1)">$return</span>['mongodb_id'] = <span style="color: rgba(128, 0, 128, 1)">$mongodb_id</span><span style="color: rgba(0, 0, 0, 1)">;
            </span><span style="color: rgba(128, 0, 128, 1)">$return</span>['filename'] = <span style="color: rgba(128, 0, 128, 1)">$file_name</span><span style="color: rgba(0, 0, 0, 1)">;
      } </span><span style="color: rgba(0, 0, 255, 1)">catch</span> (\<span style="color: rgba(0, 0, 255, 1)">Exception</span> <span style="color: rgba(128, 0, 128, 1)">$e</span><span style="color: rgba(0, 0, 0, 1)">) {
            </span><span style="color: rgba(128, 0, 128, 1)">$return</span>['msg'] = <span style="color: rgba(128, 0, 128, 1)">$e</span>-&gt;<span style="color: rgba(0, 0, 0, 1)">getMessage();
      }
   
      </span><span style="color: rgba(0, 0, 255, 1)">die</span>(json_encode(<span style="color: rgba(128, 0, 128, 1)">$return</span><span style="color: rgba(0, 0, 0, 1)">));
    }

    </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
   * 获取图片
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getImage(){
      </span><span style="color: rgba(0, 128, 128, 1)">header</span>("Content-Type:image/png"<span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(128, 0, 128, 1)">$file_name</span> = input('file_name'<span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(128, 0, 128, 1)">$file_name</span><span style="color: rgba(0, 0, 0, 1)">){
            </span><span style="color: rgba(128, 0, 128, 1)">$obj</span> = mongosStorage::<span style="color: rgba(0, 0, 0, 1)">singleEntrance();
            </span><span style="color: rgba(128, 0, 128, 1)">$file</span> = <span style="color: rgba(128, 0, 128, 1)">$obj</span>-&gt;take(<span style="color: rgba(128, 0, 128, 1)">$file_name</span><span style="color: rgba(0, 0, 0, 1)">);
            </span><span style="color: rgba(0, 0, 255, 1)">echo</span> <span style="color: rgba(128, 0, 128, 1)">$file</span><span style="color: rgba(0, 0, 0, 1)">;
      }
    }

}</span></pre>
</div>
<p>模板文件代码</p>
<div class="cnblogs_code">
<pre>&lt;div <span style="color: rgba(0, 0, 255, 1)">class</span>="layui-form-item"&gt;
      &lt;img src="{:url('/admin/Image/getImage',['file_name'=&gt;'2019102416593634834.jpg'])}"/&gt;
&lt;/div&gt;</pre>
</div>
<p>三、显示结果</p>
<p>&nbsp;<img src="https://img2018.cnblogs.com/blog/1740309/201910/1740309-20191025114606213-148231821.png"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>由于是测试,所以,没有做什么样式处理,但是,自测是可行的</p>
<p>&nbsp;</p>
<p>能用到的网址:</p>
<p>&nbsp;window下mongodb下载网址:https://www.mongodb.org/dl/win32/x86_64-2008plus-ssl?_ga=2.30821752.638885743.1535763516-1240051369.1535763516</p>
<p>mongo文档:https://docs.mongodb.com/ecosystem/drivers/php/</p>
<p>composer安装第三方库说明:https://github.com/mongodb/mongo-php-library/releases</p><br><br>
来源:https://www.cnblogs.com/FLy-1992/p/11737208.html
頁: [1]
查看完整版本: mongodb实现文件存储系统