在电商系统开发领域,PHP凭借其成熟的生态和开发效率,依然是中小型电商项目的首选语言。ThinkPHP作为国内最主流的PHP框架,以其简洁、快速和安全著称。UniApp则解决了多端适配的难题,一套代码编译到微信小程序、H5、App等多个平台。
源码及演示:xcxyms.top
一、引言:为什么选择PHP+UniApp构建现代电商系统?
本文将深度解析一套基于 ThinkPHP 6 + UniApp 的全开源高性能商城系统源码,从架构设计、核心代码实现、性能优化到服务器部署,提供一份详尽的实战指南。

二、 系统架构设计与技术选型
1. 技术栈概览
- 后端框架:ThinkPHP 6.x(基于MVC架构,支持Composer)
- 前端框架:UniApp(Vue.js语法,编译为小程序)
- 数据库:MySQL 8.0(支持JSON字段,事务处理能力强)
- 缓存系统:Redis(用于缓存热点数据、Session共享、队列)
- Web服务器:Nginx + PHP-FPM
- API规范:RESTful API,JSON数据格式
2. 目录结构规划
project/
├── server/ # 后端ThinkPHP代码
│ ├── app/
│ │ ├── controller/ # 控制器(Api接口)
│ │ ├── model/ # 模型(数据层)
│ │ ├── service/ # 业务逻辑层
│ │ └── middleware/ # 中间件(鉴权、限流)
│ ├── config/ # 配置文件
│ └── route/ # 路由定义
├── uniapp/ # 前端UniApp代码
│ ├── pages/ # 页面文件
│ ├── components/ # 组件
│ ├── static/ # 静态资源
│ └── manifest.json # 应用配置
└── docs/ # 部署文档
三、 核心模块代码实现
1. 数据库核心表设计(E-R模型)
电商系统的核心是订单与库存,以下是精简但核心的SQL结构:
-- 商品表(SPU)
CREATE TABLE `shop_goods` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL COMMENT '商品标题',
`price` decimal(10,2) NOT NULL DEFAULT '0.00',
`stock` int(11) DEFAULT '0' COMMENT '总库存',
`sales` int(11) DEFAULT '0' COMMENT '销量',
`status` tinyint(1) DEFAULT '1' COMMENT '1上架 0下架',
PRIMARY KEY (`id`),
KEY `idx_price` (`price`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 订单表
CREATE TABLE `shop_orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_sn` varchar(64) NOT NULL COMMENT '订单号',
`user_id` int(11) NOT NULL,
`total_amount` decimal(10,2) NOT NULL,
`pay_status` tinyint(1) DEFAULT '0' COMMENT '0未付 1已付',
`create_time` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_order_sn` (`order_sn`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2. 后端API开发:ThinkPHP 6 实战

(1) 跨域中间件(CORS)
由于小程序请求需要合法域名,后端必须配置跨域。
文件路径:app/middleware/Cors.php
<?php
namespace app\middleware;
class Cors
{
public function handle($request, \Closure $next)
{
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
if ($request->isOptions()) {
return response('', 200);
}
return $next($request);
}
}
(2) 商品列表接口(含分页与缓存)
文件路径:app/controller/api/Goods.php
<?php
namespace app\controller\api;
use app\BaseController;
use app\model\Goods as GoodsModel;
use think\facade\Cache;
class Goods extends BaseController
{
// 获取商品列表
public function list()
{
$page = input('page/d', 1);
$limit = input('limit/d', 10);
// 使用Redis缓存,减轻数据库压力
$cacheKey = "goods_list_{$page}_{$limit}";
$data = Cache::get($cacheKey);
if (!$data) {
$list = GoodsModel::where('status', 1)
->field('id, title, price, stock, sales')
->paginate(['page' => $page, 'list_rows' => $limit]);
$data = [
'code' => 200,
'data' => $list->items(),
'total' => $list->total()
];
// 缓存600秒
Cache::set($cacheKey, $data, 600);
}
return json($data);
}
}
(3) 订单创建与库存扣减(事务处理)
文件路径:app/service/OrderService.php
<?php
namespace app\service;
use app\model\Orders;
use app\model\Goods;
use think\facade\Db;
class OrderService
{
/**
* 创建订单(核心:防止超卖)
*/
public function createOrder($userId, $goodsId, $num)
{
Db::startTrans();
try {
// 1. 锁定商品行(悲观锁),防止并发超卖
$goods = Goods::where('id', $goodsId)->lock(true)->find();
if ($goods->stock < $num) {
throw new \Exception('库存不足');
}
// 2. 扣减库存
$goods->stock -= $num;
$goods->sales += $num;
$goods->save();
// 3. 创建订单
$order = new Orders();
$order->order_sn = date('YmdHis') . mt_rand(1000, 9999);
$order->user_id = $userId;
$order->total_amount = $goods->price * $num;
$order->save();
Db::commit();
return ['code' => 200, 'msg' => '下单成功', 'order_sn' => $order->order_sn];
} catch (\Exception $e) {
Db::rollback();
return ['code' => 500, 'msg' => $e->getMessage()];
}
}
}
3. 前端UniApp开发实战

(1) 封装统一请求(拦截器)
文件路径:uniapp/utils/request.js
const baseURL = 'https://api.yourdomain.com'; // 你的API域名
const request = (options) => {
return new Promise((resolve, reject) => {
uni.request({
url: baseURL + options.url,
method: options.method || 'GET',
data: options.data || {
},
header: {
'token': uni.getStorageSync('token') || ''
},
success: (res) => {
if (res.statusCode === 200) {
resolve(res.data);
} else {
reject(res.data);
}
},
fail: (err) => {
reject(err);
}
});
});
}
export default request;
(2) 商品列表页面
文件路径:uniapp/pages/goods/list.vue
<template>
<view class="container">
<scroll-view scroll-y @scrolltolower="loadMore">
<view v-for="item in goodsList" :key="item.id" class="goods-item">
<image :src="item.cover"></image>
<text>{
{ item.title }}</text>
<text class="price">¥{
{ item.price }}</text>
</view>
</scroll-view>
</view>
</template>
<script>
import request from '@/utils/request.js';
export default {
data() {
return {
page: 1,
goodsList: []
};
},
onLoad() {
this.getGoodsList();
},
methods: {
async getGoodsList() {
const res = await request({
url: '/api/goods/list',
data: { page: this.page }
});
if (res.code === 200) {
this.goodsList = [...this.goodsList, ...res.data];
}
},
loadMore() {
this.page++;
this.getGoodsList();
}
}
};
</script>
四、 高性能优化策略
1. 数据库优化
- 索引优化:确保
WHERE、ORDER BY、JOIN字段都有索引。 - 读写分离:主库写入,从库读取(ThinkPHP支持配置读写分离)。
- 分表策略:订单表按月份分表(如
orders_202401),防止单表过大。
2. Redis缓存应用
- 热点数据:首页Banner、商品分类、热销商品存入Redis。
- Session存储:将用户登录态存储在Redis,方便多机负载均衡。
- 分布式锁:在秒杀场景中,使用
SETNX命令防止库存超卖。
3. 接口性能
- 字段精简:API返回字段只返回前端需要的,避免大字段(如长文本)拖慢速度。
- CDN加速:商品图片、静态JS/CSS文件全部放到CDN。

五、 全开源部署指南(Linux环境)
1. 服务器环境要求
- CentOS 7 / Ubuntu 20.04
- Nginx 1.20+
- PHP 8.0+ (需安装 Redis、PDO、GD 扩展)
- MySQL 8.0+
2. Nginx 配置(重点)
server {
listen 80;
server_name api.yourdomain.com;
root /www/wwwroot/shop/server/public; # 指向ThinkPHP的public目录
location / {
index index.php index.html;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.0-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
3. 部署步骤
- 克隆代码:
git clone https://github.com/your-repo/shop.git - 安装依赖:进入
server目录,执行composer install。 - 配置数据库:复制
.env.example为.env,修改数据库配置。 - 导入SQL:将
docs/database.sql导入MySQL。 - 设置权限:
chmod -R 755 runtime(确保日志和缓存可写)。 - 配置小程序:在
uniapp/manifest.json中填写你的AppID和域名。
六、 安全与合规
- API鉴权:所有涉及用户数据的接口必须校验 Token。
- 防注入:ThinkPHP 的 ORM 已经处理了大部分 SQL 注入,但仍需对输入参数进行
intval或strip_tags过滤。 - 支付回调:微信支付回调必须验证签名,并开启 HTTPS。
- 隐私政策:小程序需配置《隐私保护指引》,明确告知用户数据收集用途。

这套 ThinkPHP + UniApp 的商城源码,兼顾了开发效率与运行性能。通过合理的架构设计(分层解耦)、高效的缓存策略(Redis)以及严谨的事务处理(防超卖),能够满足绝大多数中小型电商企业的业务需求。