thinkphp整合系列之阿里云oss
web2.0时代;除了纯信息展示类的网站;基本都是有文件上传功能的;
最不济你得让用户换个头像吧;但是随着业务的发展;
如果上传的文件都和网站程序源代码放在一起;那是有相当多的弊端的;
1:静态文件会占用大量带宽;
2:服务器的成本略高;
常规的做法是把php源代码放到一台服务器上;图片等静态文件放在另一台服务器上;
当一个神奇的“云”时代的到来后;一切就变的更加简单了;
在业务还比较小的时候;我们无需大费周折的去搞一台静态文件服务器;直接使用第三方的即可;
好了;洛里啰嗦了半天;下面请出本篇博客的主角:阿里云oss;
我就不再安利oss的优势了;还没了解过的先跟着这个链接走:https://www.aliyun.com/product/oss/
一:准备工作
1:申请key和secret
2:创建Bucket
需要注意的是要把读写权限改为: 公共读;
根据服务器的位置获取外网endpoint;https://help.aliyun.com/document_detail/31834.html
ok;凑齐了这些配置项;下面可以召唤神龙了;
二:填写配置项
依然是以项目示例:https://github.com/baijunyao/thinkphp-bjyadmin
/Application/Common/Conf/config.php
|
1
2
3
4
5
6
|
'ALIOSS_CONFIG' => array(
'KEY_ID' => '', // 阿里云oss key_id
'KEY_SECRET' => '', // 阿里云oss key_secret
'END_POINT' => '', // 阿里云oss endpoint
'BUCKET' => '' // bucken 名称
),
|
三:实例化并上传
/Application/Common/Common/function.php
注:OssClient.php 是主要的实例化对象
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
/**
* 实例化阿里云oos
* @return object 实例化得到的对象
*/
function new_oss(){
vendor('Alioss.autoload');
$config=C('ALIOSS_CONFIG');
$oss=new \OSS\OssClient($config['KEY_ID'],$config['KEY_SECRET'],$config['END_POINT']);
return $oss;
}
/**
* 上传文件到oss并删除本地文件
* @param string $path 文件路径
* @return bollear 是否上传
*/
function oss_upload($path){
// 获取配置项
$bucket=C('ALIOSS_CONFIG.BUCKET');
// 先统一去除左侧的.或者/ 再添加./
$oss_path=ltrim($path,'./');
$path='./'.$oss_path;
if (file_exists($path)) {
// 实例化oss类
$oss=new_oss();
// 上传到oss
$oss->uploadFile($bucket,$oss_path,$path);
// 如需上传到oss后 自动删除本地的文件 则删除下面的注释
// unlink($path);
return true;
}
return false;
}
|
注:主要使用OssClient.php 中的uploadFile方法来实现上传文件,$bucket,存放到OSS中的空间名,$oss_path,存放在阿里云bucket中的位置,$path,在本地文件的位置。这里要注意一下,存放在oss中的路径并不需要./ 故用ltrim函数去除可能存在的./ 而在本地存放的文件,则必须是完整的路径,因此,前面要加上./
例如:
$oss_path 'data/upload/avatar/123.png';
$path './data/upload/avatar/123.png';
最重要的就是上传文件的路径问题,如果数据库中存放的图片路径是'avatar/123.png';则在上面的代码中修改为以下即可,同时修改配置文件config中的NEED_UPLOAD_OSS路径为 'avatar'即可实现
|
1
|
$path = './data/upload/'.$oss_path;
|
ok现在首先使用框架的Upload上传类上传文件到服务器;获得文件路径;
调用oss_upload()函数;传入获得的文件路径;即可把文件上传到oss;
四:便捷方式
看第三步;我们可以发现;每上传一个文件就要调用oss_upload()函数;
那可不可以上传文件以后自动就上传到oss呢?
当然可以了;但是我们要对框架的Upload做点手术;
在 /ThinkPHP/Library/Think/Upload.class.php 的第229行添加如下代码;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
//*************************添加部分开始*************************
// 判断是否上传成功
if (!empty($info)) {
// 获取需要上传到oss的目录
$need_upload_oos=C('NEED_UPLOAD_OSS');
foreach ($info as $k => $v) {
// 判断此路径是否需要上传到oss
foreach ($need_upload_oos as $m => $n) {
if (strpos($v['savepath'], $n)!==false) {
// 上传到oss
oss_upload($v['savepath'].$v['savename']);
continue;
}
}
}
}
//*************************添加部分结束*************************
|
然后在配置项中设置哪些目录的文件自动上传到oss;
/Application/Common/Conf/config.php
|
1
2
3
4
5
6
|
'NEED_UPLOAD_OSS' => array( // 需要上传的目录
'/Upload/avatar',
'/Upload/cover',
'/Upload/image/webuploader',
'/Upload/video',
),
|
如果只有个别目不上传、或者是所有目录都上传的;直接改配置项和Upload即可;
四:获取文件链接
图片之类的静态文件是上传到oss了;那链接怎么获取呢?
/Application/Common/Common/function.php
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/**
* 获取完整网络连接
* @param string $path 文件路径
* @return string http连接
*/
function get_url($path){
// 如果是空;返回空
if (empty($path)) {
return '';
}
// 如果已经有http直接返回
if (strpos($path, 'http://')!==false) {
return $path;
}
// 判断是否使用了oss
$alioss=C('ALIOSS_CONFIG');
if (empty($alioss['KEY_ID'])) {
return 'http://'.$_SERVER['HTTP_HOST'].$path;
}else{
return 'http://'.$alioss['BUCKET'].'.'.$alioss['END_POINT'].$path;
}
}
|
调用上面这个get_url()函数;传入第三步获取到的文件路径;即可得到oss的文件链接;
到此;从创建、上传、获取文件链接;整个流程就结束了;
如果要整合到自己有的项目中;
那只需要把/ThinkPHP/Library/Vendor/Alioss文件夹拷贝到自己项目同目录下;
把上面哪些配置项和函数拿过去就可以直接用;
删除oss上的文件的函数
|
1
2
3
4
5
6
7
8
9
10
11
|
/**
* 删除oss上指定文件
* @param string $object 文件路径 例如删除 /Public/README.md文件 传Public/README.md 即可
*/
function oss_delet_object($object){
// 实例化oss类
$oss=new_oss();
// 获取bucket名称
$bucket=C('ALIOSS_CONFIG.BUCKET');
$test=$oss->deleteObject($bucket,$object);
}
|
方法还是挺简单的;唯一需要注意的是注释中写的路径的问题;
本文为白俊遥原创文章,来自白俊遥博客http://baijunyao.com 十分感谢