⭐ 最佳实践指南

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: 构建过程或辅助工具的变动

🚀 性能优化指南

1. 数据库优化

索引优化

-- 为常用查询字段添加复合索引
CREATE INDEX idx_user_status_time ON user(status, create_time);
CREATE INDEX idx_order_user_status ON orders(user_id, status);

-- 分析查询性能
EXPLAIN SELECT * FROM user WHERE status = 1 AND create_time > '2024-01-01';

查询优化

// 使用分页避免大量数据查询
$users = $this->_query('user')
    ->where('status', 1)
    ->order('create_time desc')
    ->page(20); // 每页20条

// 只查询需要的字段
$users = $this->app->db->name('user')
    ->field('id,username,email,create_time')
    ->where('status', 1)
    ->select();

2. 缓存策略

Redis 缓存

// 设置缓存
$this->app->cache->set('user_list', $users, 3600);

// 获取缓存
$users = $this->app->cache->get('user_list');
if (!$users) {
    $users = $this->getUserList();
    $this->app->cache->set('user_list', $users, 3600);
}

文件缓存

// 缓存配置信息
$config = $this->app->cache->remember('system_config', function() {
    return $this->app->db->name('config')->select();
}, 7200);

3. 前端优化

资源压缩

// 使用压缩后的资源
require(['jquery', 'layui'], function($, layui) {
    // 业务代码
});

懒加载

// 图片懒加载
$('img[data-src]').each(function() {
    var $img = $(this);
    if (isElementInViewport($img[0])) {
        $img.attr('src', $img.data('src'));
    }
});

🛠️ 开发工具推荐

1. IDE 配置

PhpStorm 配置

  • 安装 ThinkAdmin 插件
  • 配置代码格式化规则
  • 设置断点调试
  • 配置数据库连接

VS Code 配置

{
    "php.suggest.basic": false,
    "php.validate.enable": true,
    "emmet.includeLanguages": {
        "php": "html"
    }
}

2. 调试工具

Xdebug 配置

[xdebug]
zend_extension=xdebug.so
xdebug.remote_enable=1
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.idekey=PHPSTORM

日志调试

// 使用 ThinkAdmin 的日志功能
$this->app->log->info('用户登录', ['user_id' => $userId]);
$this->app->log->error('数据库错误', ['error' => $e->getMessage()]);

🔧 常见问题解决

1. 性能问题

慢查询优化

// 开启慢查询日志
$this->app->db->query("SET long_query_time = 1");
$this->app->db->query("SET slow_query_log = 1");

// 分析慢查询
$slowQueries = $this->app->db->query("SHOW SLOW QUERIES");

内存优化

// 分批处理大量数据
$batchSize = 1000;
$offset = 0;
do {
    $users = $this->app->db->name('user')
        ->limit($offset, $batchSize)
        ->select();
    
    foreach ($users as $user) {
        // 处理用户数据
    }
    
    $offset += $batchSize;
} while (count($users) === $batchSize);

2. 部署问题

环境检查

# 检查 PHP 版本
php -v

# 检查扩展
php -m | grep -E "(gd|mbstring|openssl|pdo)"

# 检查权限
ls -la runtime/

配置优化

// 生产环境配置
'debug' => false,
'log' => [
    'level' => 'error',
    'file' => 'error.log'
],
'cache' => [
    'type' => 'redis',
    'host' => '127.0.0.1',
    'port' => 6379
]

📈 监控和维护

1. 系统监控

性能监控

// 记录执行时间
$startTime = microtime(true);
// 业务逻辑
$endTime = microtime(true);
$executionTime = $endTime - $startTime;

$this->app->log->info('接口执行时间', [
    'url' => $this->request->url(),
    'time' => $executionTime
]);

错误监控

// 全局异常处理
try {
    // 业务逻辑
} catch (Exception $e) {
    $this->app->log->error('系统异常', [
        'message' => $e->getMessage(),
        'file' => $e->getFile(),
        'line' => $e->getLine(),
        'trace' => $e->getTraceAsString()
    ]);
}

2. 定期维护

数据库维护

-- 优化表
OPTIMIZE TABLE user;

-- 分析表
ANALYZE TABLE user;

-- 检查表
CHECK TABLE user;

日志清理

# 清理过期日志
find /path/to/logs -name "*.log" -mtime +30 -delete

# 压缩日志文件
gzip /path/to/logs/error.log

遵循这些最佳实践,可以确保您的 ThinkAdmin 项目更加稳定、安全和高效。持续学习和改进是开发高质量应用的关键。

最近更新:
Contributors: Anyon