⭐ 最佳实践指南

ThinkAdmin 开发项目的最佳实践和推荐做法,帮助开发者构建高质量的应用。

🚀 开发理念

核心原则

  • 代码质量: 追求高质量的代码实现
  • 性能优化: 注重系统性能和响应速度
  • 安全可靠: 确保应用的安全性和可靠性
  • 可维护性: 提高代码的可维护性和扩展性
  • 用户体验: 关注用户体验和易用性

开发目标

  • 高效开发: 提高开发效率和生产力
  • 稳定运行: 确保应用的稳定运行
  • 易于扩展: 支持功能的灵活扩展
  • 团队协作: 便于团队协作开发

🏗️ 项目结构

推荐的目录结构

project/
├── app/                    # 应用目录
│   ├── admin/             # 后台管理应用
│   ├── api/               # API 接口应用
│   ├── index/             # 前台应用
│   └── common/            # 公共应用
├── config/                # 配置文件
├── public/                # 公共资源
├── runtime/               # 运行时文件
├── vendor/                # Composer 依赖
└── composer.json          # 依赖配置

命名规范

  • 控制器: 使用 PascalCase,如 UserController
  • 模型: 使用 PascalCase,如 UserModel
  • 方法: 使用 camelCase,如 getUserList
  • 数据库表: 使用 snake_case,如 user_info
  • 字段名: 使用 snake_case,如 user_name

🔐 安全最佳实践

1. 权限控制

/**
 * 用户管理
 * @auth true    # 必须验证权限
 * @menu true    # 添加到菜单
 */
public function index()
{
    // 控制器代码
}

权限控制要点:

  • 注解权限: 使用注解方式配置权限控制
  • 细粒度控制: 支持到按钮级别的权限控制
  • 动态权限: 支持动态权限配置和管理
  • 权限继承: 支持权限继承和组合

2. 输入验证

// 使用 ThinkAdmin 的 _vali 方法
$this->_vali([
    'username.require' => '用户名不能为空',
    'username.length' => '用户名长度为3-20个字符',
    'email.require' => '邮箱不能为空',
    'email.email' => '邮箱格式不正确',
    'password.require' => '密码不能为空',
    'password.length' => '密码长度为6-20个字符'
]);

输入验证要点:

  • 数据验证: 对所有用户输入进行验证
  • 类型检查: 验证数据类型和格式
  • 长度限制: 设置合理的长度限制
  • 特殊字符: 过滤特殊字符和恶意代码
  • 错误提示: 提供清晰的错误提示信息

3. SQL 注入防护

// 使用参数绑定
$users = Db::name('user')
    ->where('username', $username)
    ->where('status', 1)
    ->select();

// 避免直接拼接 SQL
// ❌ 错误做法
$sql = "SELECT * FROM user WHERE username = '" . $username . "'";

SQL 注入防护要点:

  • 参数绑定: 使用参数绑定防止 SQL 注入
  • ORM 使用: 优先使用 ORM 进行数据库操作
  • 输入过滤: 对用户输入进行过滤和转义
  • 权限限制: 限制数据库用户权限

4. XSS 防护

// 输出时进行转义
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');

// 在模板中使用
{$userInput|default=''}

XSS 防护要点:

  • 输出转义: 对所有输出进行 HTML 转义
  • 内容过滤: 过滤危险的 HTML 标签和属性
  • CSP 策略: 使用内容安全策略
  • 输入验证: 在输入阶段进行验证和过滤

📊 数据库最佳实践

1. 索引优化

-- 为常用查询字段添加索引
CREATE INDEX idx_username ON user(username);
CREATE INDEX idx_email ON user(email);
CREATE INDEX idx_status_create_time ON user(status, create_time);

2. 查询优化

// 使用查询助手
$query = $this->_query('user');
$query->like('username', $keyword)
      ->equal('status', 1)
      ->between('create_time', $startTime, $endTime)
      ->page();

3. 分页优化

// 使用游标分页处理大数据量
$query = $this->_query('user');
$query->where('id', '>', $lastId)
      ->limit(100)
      ->order('id', 'asc');

🎨 前端开发最佳实践

1. 模板继承

<!-- 基础模板 -->
{extend name="table" /}

{block name="content"}
<div class="layui-card">
    <div class="layui-card-header">{$title}</div>
    <div class="layui-card-body">
        <!-- 页面内容 -->
    </div>
</div>
{/block}

2. 组件化开发

<!-- 可复用的表格组件 -->
{include file="atable" /}

<!-- 可复用的表单组件 -->
{include file="table" /}

3. JavaScript 模块化

// 使用 RequireJS 模块化
require(['admin'], function(admin) {
    // 页面初始化
    admin.table.render({
        elem: '#table',
        url: '/admin/user/list',
        cols: [[
            {field: 'id', title: 'ID'},
            {field: 'username', title: '用户名'}
        ]]
    });
});

🔧 性能优化

1. 缓存策略

// 使用缓存
$cacheKey = 'user_list_' . md5(serialize($params));
$data = cache($cacheKey);
if (!$data) {
    $data = $this->getUserList($params);
    cache($cacheKey, $data, 3600); // 缓存1小时
}

2. 数据库优化

// 使用查询缓存
$users = Db::name('user')
    ->cache('user_list', 3600)
    ->select();

// 避免 N+1 查询
$users = User::with(['profile', 'roles'])->select();

3. 文件存储优化

// 使用云存储
$storage = Storage::instance('qiniu');
$url = $storage->putFile($file, 'uploads/' . date('Y/m/d'));

📦 插件开发最佳实践

1. 插件结构

plugin-name/
├── src/
│   ├── Controller/        # 控制器
│   ├── Model/            # 模型
│   ├── Service/          # 服务类
│   └── View/             # 视图
├── database/             # 数据库迁移
├── public/               # 公共资源
└── composer.json         # 插件配置

2. 服务注册

// Service.php
class Service
{
    public function register()
    {
        // 注册服务
        $this->app->bind('plugin.service', PluginService::class);
    }
    
    public function boot()
    {
        // 启动服务
        $this->loadRoutes();
        $this->loadViews();
    }
}

3. 数据库迁移

// 创建迁移文件
class CreatePluginTable extends Migration
{
    public function up()
    {
        $this->table('plugin_table')
            ->addColumn('name', 'string', ['limit' => 100])
            ->addColumn('value', 'text')
            ->addColumn('created_at', 'timestamp')
            ->create();
    }
    
    public function down()
    {
        $this->table('plugin_table')->drop();
    }
}

🧪 测试最佳实践

1. 单元测试

// 测试控制器
class UserControllerTest extends TestCase
{
    public function testIndex()
    {
        $response = $this->get('/admin/user');
        $response->assertStatus(200);
    }
    
    public function testCreate()
    {
        $data = [
            'username' => 'test',
            'email' => 'test@example.com'
        ];
        
        $response = $this->post('/admin/user/create', $data);
        $response->assertStatus(200);
    }
}

2. 功能测试

// 测试完整功能流程
public function testUserManagement()
{
    // 1. 创建用户
    $user = $this->createUser();
    
    // 2. 登录
    $this->login($user);
    
    // 3. 访问用户列表
    $response = $this->get('/admin/user');
    $response->assertSee($user->username);
    
    // 4. 编辑用户
    $response = $this->put('/admin/user/update/' . $user->id, [
        'nickname' => '新昵称'
    ]);
    $response->assertStatus(200);
}

📝 代码规范

1. PHP 代码规范

<?php
namespace app\admin\controller;

use think\admin\Controller;
use think\admin\model\User;

/**
 * 用户管理控制器
 * 
 * @author Your Name
 * @since 1.0.0
 */
class UserController extends Controller
{
    /**
     * 用户列表
     * 
     * @auth true
     * @menu true
     * @return mixed
     */
    public function index()
    {
        $this->title = '用户管理';
        $this->fetch();
    }
}

2. 注释规范

/**
 * 获取用户信息
 * 
 * @param int $id 用户ID
 * @param bool $withProfile 是否包含详细信息
 * @return array|false 用户信息数组或false
 * @throws \Exception 当用户不存在时抛出异常
 */
public function getUserInfo($id, $withProfile = false)
{
    // 方法实现
}

🚀 部署最佳实践

1. 生产环境配置

// config/app.php
return [
    'app_debug' => false,
    'app_trace' => false,
    'log' => [
        'level' => 'error',
        'file_size' => 2097152,
    ],
];

2. 性能监控

// 添加性能监控
$startTime = microtime(true);
// 执行业务逻辑
$endTime = microtime(true);
$executionTime = $endTime - $startTime;

// 记录慢查询
if ($executionTime > 1.0) {
    Log::warning('Slow query detected', [
        'execution_time' => $executionTime,
        'sql' => $sql
    ]);
}

3. 错误处理

// 全局异常处理
try {
    // 业务逻辑
} catch (\Exception $e) {
    Log::error('Business error', [
        'message' => $e->getMessage(),
        'file' => $e->getFile(),
        'line' => $e->getLine(),
        'trace' => $e->getTraceAsString()
    ]);
    
    $this->error('操作失败,请稍后重试');
}

📚 文档最佳实践

1. 代码文档

  • 为每个类和方法添加注释
  • 使用标准的 PHPDoc 格式
  • 包含参数说明和返回值说明
  • 添加使用示例

2. API 文档

  • 提供完整的 API 接口文档
  • 包含请求参数和响应格式
  • 提供多种语言的示例代码
  • 定期更新文档内容

🔄 版本控制最佳实践

1. Git 工作流

# 功能开发
git checkout -b feature/user-management
git add .
git commit -m "feat: 添加用户管理功能"
git push origin feature/user-management

# 创建 Pull Request
# 代码审查通过后合并到主分支

2. 提交信息规范

feat: 新功能
fix: 修复bug
docs: 文档更新
style: 代码格式调整
refactor: 代码重构
test: 测试相关
chore: 构建过程或辅助工具的变动

遵循这些最佳实践,可以确保您的 ThinkAdmin 项目更加稳定、安全和高效。