开发者社区> 问答> 正文

Wordpress附件上传到OSS存储SDK应用实例


OSS 作为开放存储服务,其最大的作用就是作为一个大仓库来存放你所有的静态文件。这其中应用最多的场景就是作为图床。期初我感觉阿里云 OSS 结合自身网站并不是那么特别简单就能实现,不过现在利用官方的 SDK 开发包来实现 OSS 开放存储难度就没那么大了。但不是每个人都有能力利用 SDK 来实现 OSS 的利用。下面我以 Wordpress 应用场景为例简单介绍下 OSS 的创建方法,重点介绍如何用 SDK 来上传、删除附件等常见需求。

1、创建 Bucket :过程很简单,直接上图看看算了。注意选择正确的读写权限。所属地域应该与你的 ECS 在同一地域,以减少延时。

图 1
2、Bucket 默认页面设置:你可以设置自己的默认首页文件及 404 错误页面。

图 2
3、Bucket 访问白名单设置:可以用通配符的形式设置白名单,只有通过 URL 签名或者匿名访问 Object 时,才会做防盗链验证。

图 3
4、绑定域名:这步很简单,记得给要绑定的域名做 cname 到 oss 子域名。

图 4
5、开通图片处理:图片处理服务需开通 CDN 服务才能开启。设置你要绑定的域名,并上传验证文件进行验证通过后即可开通。

图 5


图 6

OSS 的开通过程还是很简单的,这个不是本文要重点说明的,重点的问题是如何才能把Wordpress附件自动同步上传到 OSS 。下面直接贴代码以实例说明:
require_once('sdk.class.php');
// 初始化选项
register_activation_hook(__FILE__, 'oss_set_options');

/**
* 初始化选项
*/
function oss_set_options() {
    $options = array(
        'bucket' => "",
        'ak' => "",
        'sk' => "",
        'host' => "oss.aliyuncs.com",
        'nothumb' => "false",
        'nolocalsaving' => "false",
        'upload_url_path' => "",
        
    );
    
    add_option('oss_options', $options, '', 'yes');
}

/**
*上传函数
*@param $object
*@param $file
*@param $opt
*@return bool
*/
function _file_upload( $object , $file , $opt = array()){
    //设置超时时间
    //set_time_limit(120);
    
    //如果文件不存在,直接返回FALSE
    if( !@file_exists($file) )
        return FALSE;
        
    //获取WP配置信息
    $oss_options = get_option('oss_options', TRUE);
    $oss_bucket = attribute_escape($oss_options['bucket']);
    $oss_ak = attribute_escape($oss_options['ak']);
    $oss_sk = attribute_escape($oss_options['sk']);
    $oss_host = attribute_escape($oss_options['host']);
    if($oss_host==null || $oss_host == '')
        $oss_host = 'oss.aliyuncs.com';

    if(@file_exists($file)) {
        try {
            //实例化存储对象
            if(!is_object($aliyun_oss))
                $aliyun_oss = new ALIOSS($oss_ak, $oss_sk ,$oss_host);
            //上传原始文件,$opt暂时没有使用
            $aliyun_oss->upload_file_by_file( $oss_bucket, $object, $file, $opt );

            return TRUE;
            
        } catch(Exception $ex) {
            return FALSE;
        }
        
    } else {
        return FALSE;
    }
}


/**
* 是否需要删除本地文件
* @return bool
*/
function _is_delete_local_file() {
    $oss_options = get_option('oss_options', TRUE);
    return (attribute_escape($oss_options['nolocalsaving'])=='true');
}

/**
* 删除本地文件
*
* @param $file 本地文件路径
* @return bool
*/
function _delete_local_file($file){
    try{
      //文件不存在
        if(!@file_exists($file))
            return TRUE;
        //删除文件
        if(!@unlink($file))
            return FALSE;
        return TRUE;
    }
    catch(Exception $ex){
        return FALSE;
    }
}


/**
* 在OSS中记录日志信息
* @param $logpath 日志存放路径
* @param $content 写入的内容
* @return bool
*/
function _logged($logpath,$content) {
    //获取WP配置信息
    $oss_options = get_option('oss_options', TRUE);
    $oss_bucket = attribute_escape($oss_options['bucket']);
    $oss_ak = attribute_escape($oss_options['ak']);
    $oss_sk = attribute_escape($oss_options['sk']);
    $oss_host = attribute_escape($oss_options['host']);
    if($oss_host==null || $oss_host == '')
        $oss_host = 'oss.aliyuncs.com';

    try {
        //实例化存储对象
        if(!is_object($aliyun_oss))
            $aliyun_oss = new ALIOSS($oss_ak, $oss_sk ,$oss_host);
        //上传原始文件,$opt暂时没有使用
        $upload_file_options = array(
            'content' => $content,
            'length' => strlen($content),
            ALIOSS::OSS_HEADERS => array(
                'Expires' => '2012-10-01 08:00:00',
            ),
        );
        $aliyun_oss->upload_file_by_content( $oss_bucket, $logpath, $upload_file_options );

        return TRUE;
        
    } catch(Exception $ex) {
        return FALSE;
    }
}

/**
* 上传附件(包括图片的原图)
* @param $metadata
* @return array()
*/
function upload_attachments($metadata) {
    $wp_uploads = wp_upload_dir();
    //生成object在OSS中的存储路径
    if(get_option('upload_path') == '.') {
        //如果含有“./”则去除之
        $metadata['file'] = str_replace("./" ,'' ,$metadata['file']);    
    }
    $object = str_replace(get_home_path(), '', $metadata['file']);
    
    //在本地的存储路径
    //$file = $metadata['file'];
    $file = get_home_path().$object;    //向上兼容,较早的WordPress版本上$metadata['file']存放的是相对路径
    
    //设置可选参数
    $opt =array('Content-Type' => $metadata['type']);
    
    //执行上传操作
    _file_upload ( $object, $file, $opt);
    //_logged('2upload.txt',"object=$object;file=$file");
    
    //如果不在本地保存,则删除本地文件
    if( _is_delete_local_file() ){
        _delete_local_file($file);
    }
    
    return $metadata;
}
//避免上传插件/主题时出现同步到OSS的情况
if(substr_count($_SERVER['REQUEST_URL'],'/update.php') <= 0)
    add_filter('wp_handle_upload', 'upload_attachments', 50);


/**
* 上传图片的缩略图
* @param $metadata
* @return array
*/
function upload_thumbs($metadata) {
    //上传所有缩略图
    if (isset($metadata['sizes']) && count($metadata['sizes']) > 0)
    {
        //获取OSS插件的配置信息
        $oss_options = get_option('oss_options', TRUE);
        //是否需要上传缩略图
        $nothumb = (attribute_escape($oss_options['nothumb']) == 'true');
        //是否需要删除本地文件
        $is_delete_local_file = (attribute_escape($oss_options['nolocalsaving'])=='true');
        
        //如果禁止上传缩略图,就不用继续执行了
        if( $nothumb ) {
            return $metadata;
        }
        
        //获取上传路径
        $wp_uploads = wp_upload_dir();
        //得到本地文件夹和远端文件夹
        $file_path = $wp_uploads['path'].'/';
        if(get_option('upload_path') == '.') {
            $file_path = str_replace("./" ,'' , $file_path);
        }
        $object_path = str_replace(get_home_path(), '', $file_path);
        
        
        //there may be duplicated filenames,so ....
        foreach ($metadata['sizes'] as $val)
        {
            //生成object在OSS中的存储路径
            $object = $object_path.$val['file'];
            //生成本地存储路径
            $file = $file_path . $val['file'];
            //设置可选参数
            $opt =array('Content-Type' => $val['mime-type']);
            
            //执行上传操作
            _file_upload ( $object, $file, $opt );
            //_logged('2thumb.txt',"object=$object;file=$file");
            
            //如果不在本地保存,则删除
            if($is_delete_local_file)
                _delete_local_file($file);
        }
    }
    
    return $metadata;
}
//避免上传插件/主题时出现同步到OSS的情况
if(substr_count($_SERVER['REQUEST_URL'],'/update.php') <= 0)
    add_filter('wp_generate_attachment_metadata', 'upload_thumbs', 100);


/**
* 删除远程服务器上的单个文件
* @static
* @param $file
* @return void
*/
function delete_remote_file($file)
{    
    
    //获取WP配置信息
    $oss_options = get_option('oss_options', TRUE);
    $oss_bucket = attribute_escape($oss_options['bucket']);
    $oss_ak = attribute_escape($oss_options['ak']);
    $oss_sk = attribute_escape($oss_options['sk']);
    $oss_host = attribute_escape($oss_options['host']);
    if($oss_host==null || $oss_host == '')
        $oss_host = 'oss.aliyuncs.com';
    
    //得到远端路径
    $del_file_path = str_replace(get_home_path(), '', $file);
    //_logged('2delete.txt',"del_file_path=$del_file_path");
    try{
        //实例化存储对象
        if(!is_object($aliyun_oss))
            $aliyun_oss = new ALIOSS($oss_ak, $oss_sk, $oss_host);
        //删除文件
        $aliyun_oss->delete_object( $oss_bucket, $del_file_path);
    } catch(Exception $ex){}

    return $file;
}
add_action('wp_delete_file', 'delete_remote_file', 100);
以上代码只是以实例说明如何应用SDK,具体到自己的应用上,还得看你准备怎么用OSS。我对OSS的SDK套件的认识还属比较浅的程度。OSS提供了可靠稳定地第三方存储服务,有了OSS和RDS,你就可以放心地倒腾你ECS上的程序代码,无论有多少图片都不怕空间不足,同时还有CDN服务配套。OSS现在最大的不足就在于缺少原生FTP上传,如果能官方原生支持FTP上传对初级用户的上手难度将降低很多很多!

展开
收起
bailimei 2015-04-20 01:41:41 15219 0
6 条回答
写回答
取消 提交回答
  • ReWordpress附件上传到OSS存储SDK应用实例
    SDK我觉得好难上手。好贴得顶!
    2015-04-22 16:40:40
    赞同 展开评论 打赏
  • 对我目前正在开发的项目有很好的借鉴意义
    2015-04-21 18:30:35
    赞同 展开评论 打赏
  • ReWordpress附件上传到OSS存储SDK应用实例
    马克一下,下次再弄弄。谢谢楼主分享。
    2015-04-21 13:29:58
    赞同 展开评论 打赏
  • 实用的SDK应用代码,必须要顶一个!
    2015-04-21 10:40:28
    赞同 展开评论 打赏
  • ReWordpress附件上传到OSS存储SDK应用实例
    楼上兄弟您也忒辛苦了吧,凌晨三点多发帖回复!泪流满面!
    2015-04-20 18:33:47
    赞同 展开评论 打赏
  • ReWordpress附件上传到OSS存储SDK应用实例
    不错的文章。顶一下。
    2015-04-20 04:03:35
    赞同 展开评论 打赏
滑动查看更多
问答排行榜
最热
最新

相关电子书

更多
从 SDK 到编解码:视频直播架构解析 立即下载
跨平台的云服务SDK需要什么 立即下载
一个跨平台的云服务SDK需要什么 立即下载