核心原理:数据接口化
理解这个原理是关键,传统的织梦网站是 PHP 模板直接渲染 HTML 的,而小程序需要的是纯数据(通常是 JSON 格式),我们需要在织梦系统中创建一个“数据接口”,小程序通过这个接口获取数据,然后自己进行渲染。

工作流程图:
[小程序前端] --- (请求数据) ---> [织梦后端API接口] --- (查询数据库) ---> [织梦数据库]
|
V
[返回JSON数据] <--- (处理数据) ---
|
V
[小程序前端] --- (接收JSON) ---> (渲染页面)
技术选型与准备工作
在开始之前,你需要准备以下环境和工具:
-
服务器环境:
- 一台支持 PHP 的 Web 服务器(如 Apache 或 Nginx)。
- 数据库(通常是 MySQL)。
- 已安装并正常运行织梦(DedeCMS)系统,确保你有服务器的 FTP/SFTP 权限,以便修改文件。
-
开发工具:
(图片来源网络,侵删)- 微信开发者工具:这是开发小程序的必备官方工具。
- 代码编辑器:如 VS Code、Sublime Text,用于编辑织梦的 PHP 文件和小程序的代码。
-
小程序账号:
- 一个在微信公众平台注册的小程序账号,获取
AppID。
- 一个在微信公众平台注册的小程序账号,获取
详细开发步骤
我们将以“获取文章列表”和“获取文章详情”这两个最常用的功能为例。
第一步:在织梦系统中创建 API 接口
这是整个流程的核心,我们创建一个 PHP 文件,它负责接收请求,查询数据库,并返回 JSON 数据。
-
创建 API 文件: 通过 FTP 连接到你的服务器,在织梦的根目录(通常是 或
/dede/)下创建一个新文件夹,api,在api文件夹中创建一个新的 PHP 文件,index.php。
(图片来源网络,侵删) -
编写 API 代码: 打开
api/index.php文件,编写以下代码,这段代码会根据 URL 中的type参数来决定返回哪种数据。<?php // 1. 设置响应头为 JSON 格式 header('Content-Type:application/json; charset=utf-8'); // 2. 引入织梦的核心文件,以便使用其数据库连接和函数 // 注意:这里的路径需要根据你的织梦安装位置进行调整 require_once('../include/common.inc.php'); // 3. 获取小程序传递过来的参数 $type = isset($_GET['type']) ? trim($_GET['type']) : ''; // 4. 根据不同的 type 返回不同的数据 $result = array(); if ($type == 'article_list') { // 获取文章列表 $pageSize = isset($_GET['pageSize']) ? intval($_GET['pageSize']) : 10; // 每页条数 $pageIndex = isset($_GET['pageIndex']) ? intval($_GET['pageIndex']) : 1; // 当前页码 $start = ($pageIndex - 1) * $pageSize; // 使用织梦的数据库查询函数 // 这里查询 dede_archives 表(文章主表) $sql = "SELECT id, title, litpic, description, pubdate FROM dede_archives WHERE arcrank > -1 ORDER BY id DESC LIMIT {$start}, {$pageSize}"; $dsql->SetQuery($sql); $dsql->Execute(); $articles = array(); while ($row = $dsql->GetArray()) { // 处理数据,使其更符合小程序前端的使用习惯 $articles[] = array( 'id' => $row['id'], 'title' => $row['title'], 'image' => $row['litpic'], // 文章缩略图 'summary' => $row['description'], // 'date' => date('Y-m-d H:i:s', $row['pubdate']) // 发布时间 ); } $result['status'] = 1; $result['msg'] = '获取文章列表成功'; $result['data'] = $articles; } elseif ($type == 'article_detail') { // 获取文章详情 $id = isset($_GET['id']) ? intval($_GET['id']) : 0; if ($id > 0) { // 使用织梦的 GetOne 函数获取单条记录 $article = $dsql->GetOne("SELECT * FROM dede_archives WHERE id = {$id}"); if ($article) { // 获取文章正文内容,在 dede_addonarticle 表中 $body = $dsql->GetOne("SELECT body FROM dede_addonarticle WHERE aid = {$id}"); // 处理数据 $result['status'] = 1; $result['msg'] = '获取文章详情成功'; $result['data'] = array( 'id' => $article['id'], 'title' => $article['title'], 'image' => $article['litpic'], 'content' => $body['body'], // 富文本内容 'date' => date('Y-m-d H:i:s', $article['pubdate']) ); } else { $result['status'] = 0; $result['msg'] = '文章不存在'; } } else { $result['status'] = 0; $result['msg'] = '文章ID无效'; } } else { // 未知类型 $result['status'] = 0; $result['msg'] = '请求类型错误'; } // 5. 输出 JSON 数据 echo json_encode($result, JSON_UNESCAPED_UNICODE); ?> -
测试 API: 在浏览器中访问你的 API 地址,
http://你的域名/api/index.php?type=article_list,如果能看到返回的 JSON 数据,说明接口已经成功创建。
第二步:创建小程序项目
- 打开微信开发者工具,使用你的
AppID创建一个新的小程序项目。 - 在
pages目录下,创建两个页面:index(首页/文章列表)和detail(文章详情)。
第三步:在小程序中调用 API 并渲染数据
首页 (pages/index/index.js - 获取数据)
// pages/index/index.js
Page({
data: {
articleList: [],
pageIndex: 1,
isLoading: false
},
onLoad: function (options) {
this.loadArticleList();
},
// 加载文章列表的方法
loadArticleList: function() {
if (this.data.isLoading) return; // 防止重复加载
this.setData({ isLoading: true });
wx.request({
url: 'http://你的域名/api/index.php', // 你的织梦API地址
data: {
type: 'article_list',
pageIndex: this.data.pageIndex,
pageSize: 10
},
method: 'GET',
success: (res) => {
if (res.data.status === 1) {
// 将新获取的数据追加到现有列表中
let newList = this.data.articleList.concat(res.data.data);
this.setData({
articleList: newList,
pageIndex: this.data.pageIndex + 1
});
}
},
fail: (err) => {
console.error('请求失败', err);
wx.showToast({
title: '加载失败',
icon: 'none'
});
},
complete: () => {
this.setData({ isLoading: false });
}
});
},
// 下拉刷新
onPullDownRefresh: function() {
this.setData({
articleList: [],
pageIndex: 1
});
this.loadArticleList();
wx.stopPullDownRefresh();
},
// 上拉加载更多
onReachBottom: function() {
this.loadArticleList();
}
});
首页 (pages/index/index.wxml - 模板渲染)
<!-- pages/index/index.wxml -->
<view class="container">
<block wx:for="{{articleList}}" wx:key="id">
<view class="article-item" bindtap="goToDetail" data-id="{{item.id}}">
<image class="article-image" src="{{item.image}}" mode="aspectFill"></image>
<view class="article-info">
<view class="article-title">{{item.title}}</view>
<view class="article-summary">{{item.summary}}</view>
<view class="article-date">{{item.date}}</view>
</view>
</view>
</block>
<view wx:if="{{isLoading}}" class="loading">加载中...</view>
<view wx:if="{{articleList.length === 0 && !isLoading}}" class="empty">暂无数据</view>
</view>
首页 (pages/index/index.js - 跳转详情页)
在 index.js 中添加 goToDetail 方法:
// 在 index.js 中添加
goToDetail: function(e) {
const id = e.currentTarget.dataset.id;
wx.navigateTo({
url: '/pages/detail/detail?id=' + id,
});
},
详情页 (pages/detail/detail.js - 获取详情数据)
// pages/detail/detail.js
Page({
data: {
article: null
},
onLoad: function (options) {
const id = options.id;
if (id) {
this.loadArticleDetail(id);
} else {
wx.showToast({
title: '文章ID错误',
icon: 'none'
});
}
},
loadArticleDetail: function(id) {
wx.request({
url: 'http://你的域名/api/index.php',
data: {
type: 'article_detail',
id: id
},
method: 'GET',
success: (res) => {
if (res.data.status === 1) {
this.setData({ article: res.data.data });
} else {
wx.showToast({
title: res.data.msg,
icon: 'none'
});
}
},
fail: (err) => {
console.error('请求失败', err);
wx.showToast({
title: '加载失败',
icon: 'none'
});
}
});
}
});
详情页 (pages/detail/detail.wxml - 渲染详情)
<!-- pages/detail/detail.wxml -->
<view class="container" wx:if="{{article}}">
<image class="detail-image" src="{{article.image}}" mode="widthFix"></image>
<view class="detail-title">{{article.title}}</view>
<view class="detail-date">{{article.date}}</view>
<!-- 使用 rich-text 组件来渲染富文本内容 -->
<rich-text nodes="{{article.content}}"></rich-text>
</view>
<view wx:else class="empty">加载中...</view>
重要注意事项
-
跨域问题:
- 小程序请求的域名必须在小程序后台的“开发” -> “开发管理” -> “开发设置” -> “服务器域名”中配置,你需要将你的织梦域名(如
http://你的域名)添加到request合法域名列表中。 - 如果你的织梦版本较低,PHP 可能没有开启
curl扩展,或者没有配置好,这会导致wx.request失败。
- 小程序请求的域名必须在小程序后台的“开发” -> “开发管理” -> “开发设置” -> “服务器域名”中配置,你需要将你的织梦域名(如
-
数据安全:
- 上述 API 是公开的,任何人都可以访问,并且可以进行任意 SQL 查询(如
api/index.php?type=article_list&id=1),这在生产环境中是极其危险的。 - 解决方案:
- 增加参数校验:在 API 中增加一个
token或sign参数,小程序在请求时,根据某种规则(如 MD5 加密)生成一个签名,后端验证签名是否正确。 - 限制 IP:在服务器层面(如 Nginx 配置)只允许你的小程序服务器或特定 IP 访问 API 文件夹。
- 最小权限原则:为 API 专门创建一个数据库用户,并只授予其
SELECT(查询)权限,不给UPDATE,DELETE,INSERT权限。
- 增加参数校验:在 API 中增加一个
- 上述 API 是公开的,任何人都可以访问,并且可以进行任意 SQL 查询(如
-
兼容性:
- 织梦编辑器(如ckeditor)生成的 HTML 代码可能包含小程序
rich-text组件不支持的标签或属性(如<font>,<table>,<span style="...">)。 - 解决方案:在返回数据前,使用 PHP 的字符串处理函数(如
strip_tags)或正则表达式,对body字段进行过滤,只保留<p>,<img>,<b>,<i>,<br>等基本标签。
- 织梦编辑器(如ckeditor)生成的 HTML 代码可能包含小程序
-
图片路径问题:
- 从数据库中获取的图片路径(
litpic)可能是相对路径(如/uploads/2025/10/xxx.jpg)。 - 解决方案:在 API 返回数据时,将图片路径拼接成完整的 URL,如
http://你的域名+row['litpic']。
- 从数据库中获取的图片路径(
进阶与优化
- 使用 JWT 进行用户认证:如果小程序需要用户登录,可以在织梦中集成用户系统,并通过 JWT (JSON Web Token) 的方式在小程序和后端之间进行身份验证。
- 使用缓存:对于不常变化的数据(如文章分类、首页推荐),可以在小程序端使用
wx.setStorage进行本地缓存,减少对 API 的请求。 - 使用更现代的框架:织梦是一个比较老 CMS,如果你对性能和扩展性有更高要求,可以考虑将织梦作为“数据源”,使用更现代的后端技术(如 Node.js + Express, Python + Django/Flask)来专门构建 API,这样更灵活、更安全。
通过以上步骤,你就可以成功地将你的织梦网站内容“赋能”给一个小程序了,这个过程的核心就是将传统 CMS 转化为一个数据服务提供者。
