插件化对接的意义
直接改织梦上传逻辑虽然能实现 OSS 接入,但每次升级都要重做一遍,维护成本高。把 OSS 对接封装为标准织梦插件,遵循织梦模块规范,安装、配置、启停都在后台完成,与主程序解耦。这样既能复用到多个站点,也方便后续增加腾讯云 COS、七牛等存储后端,形成可插拔的存储层。
插件目录结构
plus/ossupload/
├── config.php // 后台配置表单
├── install.php // 安装钩子
├── uninstall.php // 卸载钩子
├── ossupload.class.php // 核心类
├── lib/ // OSS SDK
│ └── ...
└── readme.txt // 说明文档
遵循织梦 plus 目录规范,安装时复制到 /plus/ossupload/,在后台模块管理中可见。
核心类设计
封装统一接口 OssUploader,对外暴露 upload、delete、getUrl 三个方法:
<?php
// plus/ossupload/ossupload.class.php
require_once DEDEINC.'/ossupload/lib/autoload.php';
use OSS\OssClient;
use OSS\Core\OssException;
class OssUploader {
private $oss;
private $bucket;
private $prefix;
private $cdn;
public function __construct() {
global $dsql;
$row=$dsql->GetOne("SELECT * FROM dede_ossconfig WHERE id=1");
$this->oss=new OssClient(
$row['accesskey'], $row['secret'], $row['endpoint']
);
$this->bucket=$row['bucket'];
$this->prefix=$row['prefix'];
$this->cdn=$row['cdn_domain'];
}
public function upload($localFile, $object) {
$key=$this->prefix . $object;
$this->oss->uploadFile($this->bucket, $key, $localFile);
return $this->cdn . '/' . $key;
}
public function delete($object) {
return $this->oss->deleteObject($this->bucket, $this->prefix . $object);
}
public function getUrl($object) {
return $this->cdn . '/' . $this->prefix . $object;
}
}
?>
钩入织梦上传流程
织梦上传走 include/dialog/select_images_post.php 与 include/helpers/upload.helper.php。在原上传成功后调用插件:
// 在 move_uploaded_file 成功后追加
if ($cfg_oss_enable=='Y') {
require_once DEDEINC.'/ossupload/ossupload.class.php';
$uploader=new OssUploader();
$ossUrl=$uploader->upload($file_path, $filename);
// 用 $ossUrl 覆盖返回的 URL
$fileurl=$ossUrl;
// 可选:删除本地副本
@unlink($file_path);
}
在 include/common.inc.php 加载开关:
// 读取 OSS 开关
$cfg_oss_enable='N';
$row=$dsql->GetOne("SELECT enabled FROM dede_ossconfig WHERE id=1");
if ($row) $cfg_oss_enable=$row['enabled']==1 ? 'Y' : 'N';
后台配置表单
config.php 提供表单写入 dede_ossconfig 表:
CREATE TABLE IF NOT EXISTS `dede_ossconfig` (
`id` tinyint(1) NOT NULL DEFAULT '1',
`enabled` tinyint(1) NOT NULL DEFAULT '0',
`accesskey` varchar(64) NOT NULL,
`secret` varchar(128) NOT NULL,
`endpoint` varchar(128) NOT NULL,
`bucket` varchar(64) NOT NULL,
`prefix` varchar(64) NOT NULL DEFAULT 'uploads/',
`cdn_domain` varchar(128) NOT NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM;
表单字段:启用开关、AccessKey、Secret、Endpoint、Bucket、前缀、CDN 域名、测试按钮。测试按钮触发一次小文件上传,验证配置正确。
安全性加固
- Secret 字段在表单显示时脱敏,写入时加密存储。
- Endpoint 优先用内网域名,避免公网流量费。
- Bucket 开启服务端加密 SSE-KMS。
- RAM 子账号仅授 PutObject、GetObject、DeleteObject。
- 配置文件单独存放,权限 600。
建议把 AccessKey/Secret 写入
data/oss.secret.php 并加 deny from all,避免通过 Web 泄露。安装与卸载
安装 install.php
// 建表、写入默认空配置
$dsql->ExecuteNoneQuery("CREATE TABLE ...");
$dsql->ExecuteNoneQuery("INSERT INTO dede_ossconfig SET id=1");
// 写入钩子文件
@file_put_contents(DEDEINC.'/oss.hook.php', '<?php ...');
卸载 uninstall.php
// 删除配置表与钩子,保留已上传文件
$dsql->ExecuteNoneQuery("DROP TABLE IF EXISTS dede_ossconfig");
@unlink(DEDEINC.'/oss.hook.php');
建议与后续
插件完成并稳定运行后,建议把存储抽象成接口,预留腾讯云 COS、七牛、S3 等适配器,让插件支持多云后端。在后台增加“上传统计”页,展示当天上传量、成功率、平均耗时,方便观察 OSS 健康度。把插件版本与织梦版本兼容矩阵维护到 readme,每次织梦升级前对照测试,确保插件可平滑跟随主程序迭代。