⭐ 最佳实践

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

🚀 开发理念

核心原则

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

开发目标

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

🏗️ 项目结构

推荐的目录结构

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

命名规范

类命名规范

  • 控制器: 使用 PascalCase,如 UserMenuConfig
  • 模型: 使用 PascalCase,必须以 System 开头,如 SystemUserSystemMenu
  • 服务类: 使用 PascalCase,以 Service 结尾,如 AdminServiceMenuService
  • Helper 类: 使用 PascalCase,以 Helper 结尾,如 QueryHelperFormHelper

方法命名规范

  • 公共方法: 使用 camelCase,如 index()add()edit()remove()
  • 私有方法: 使用下划线前缀,如 _form_filter()_page_filter()
  • 钩子方法: 使用下划线前缀和特定后缀,如 _form_filter()_form_result()_index_page_filter()

数据库命名规范

  • 表名: 使用 snake_case,必须以应用模块名称作为前缀,如 system_usersystem_menu(system 模块)、account_user(account 模块)、wechat_auth(wechat 模块)
  • 字段名: 使用 snake_case,如 create_atupdate_atis_deleted
  • 主键: 统一使用 id 作为主键字段名
  • 时间字段: 使用 create_atupdate_atdelete_at 格式

变量命名规范

  • 类属性: 使用 camelCase,如 $this->title$this->menus
  • 局部变量: 使用 camelCase,如 $data$query$user
  • 数组键名: 使用 snake_case,如 $data['user_id']$data['create_at']

🔐 安全最佳实践

1. 权限控制

权限注解使用

/**
 * 系统用户管理
 * @auth true    # 必须验证权限
 * @menu true    # 添加到菜单
 */
public function index()
{
    $this->title = '系统用户管理';
    SystemUser::mQuery()->layTable();
}

/**
 * 添加系统用户
 * @auth true    # 需要权限验证
 */
public function add()
{
    SystemUser::mForm('form');
}

/**
 * 修改用户资料
 * @login true   # 只需要登录即可访问
 */
public function info()
{
    // 个人资料修改,登录用户即可访问
}

权限控制要点:

  • 注解权限: 使用 @auth true 注解配置权限控制
  • 菜单显示: 使用 @menu true 注解添加到系统菜单
  • 登录验证: 使用 @login true 注解进行登录验证
  • 细粒度控制: 支持到按钮级别的权限控制
  • 动态权限: 支持动态权限配置和管理
  • 权限继承: 支持权限继承和组合

权限检查方法

// 检查是否为超级管理员
if (AdminService::isSuper()) {
    // 超级管理员逻辑
}

// 获取当前用户ID
$userId = AdminService::getUserId();

// 检查用户登录状态
if (AdminService::isLogin()) {
    // 已登录逻辑
}

2. 输入验证

使用 _vali 方法验证

// 在控制器方法中使用
public function save()
{
    $data = $this->_vali([
        'id.require'                  => '用户ID不能为空!',
        'password.require'            => '登录密码不能为空!',
        'repassword.require'          => '重复密码不能为空!',
        'repassword.confirm:password' => '两次输入的密码不一致!',
    ]);
    
    // 验证通过后继续处理
}

// 在表单过滤中使用
protected function _form_filter(array &$data)
{
    if ($this->request->isPost()) {
        $this->_vali([
            'username.require' => '登录账号不能为空!',
            'email.email'      => '邮箱格式不正确!',
            'status.in:0,1'    => '状态值范围异常!',
        ]);
    }
}

验证规则说明

  • require: 必填验证
  • email: 邮箱格式验证
  • mobile: 手机号格式验证
  • length: 长度验证
  • in: 值范围验证,如 in:0,1 表示只能是 0 或 1
  • confirm: 确认验证,如 confirm:password 表示与 password 字段值必须一致

输入验证要点:

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

3. SQL 注入防护

// 使用参数绑定(推荐使用模型方法)
$users = SystemUser::mk()
    ->where('username', $username)
    ->where('status', 1)
    ->select();

// 或使用 Db 助手(表名需包含模块前缀)
$users = Db::name('system_user')
    ->where('username', $username)
    ->where('status', 1)
    ->select();

// 避免直接拼接 SQL
// ❌ 错误做法
$sql = "SELECT * FROM system_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 system_user(username);
CREATE INDEX idx_email ON system_user(email);
CREATE INDEX idx_status_create_at ON system_user(status, create_at);

2. 查询优化

使用 QueryHelper 进行查询

// 方式一:控制器中使用
SystemUser::mQuery()->layTable(function () {
    $this->title = '系统用户管理';
    $this->bases = SystemBase::items('身份权限');
}, function (QueryHelper $query) {
    $query->where(['is_deleted' => 0, 'status' => 1]);
    $query->equal('status,usertype')->dateBetween('login_at,create_at');
    $query->like('username|nickname#username,contact_phone#phone');
});

// 方式二:使用模型方法
$query = SystemUser::mQuery();
$query->like('username,email')
      ->equal('status')
      ->dateBetween('create_at')
      ->order('id desc')
      ->page();

查询条件方法

  • like(): 模糊查询,如 like('username,nickname')
  • equal(): 精确查询,如 equal('status,type')
  • dateBetween(): 日期范围查询,如 dateBetween('create_at')
  • timeBetween(): 时间范围查询,如 timeBetween('enter_time')
  • where(): 自定义查询条件
  • order(): 排序,如 order('id desc')

3. 分页优化

// 使用游标分页处理大数据量(推荐使用模型方法)
$query = SystemUser::mQuery();
$query->where('id', '>', $lastId)
      ->where(['is_deleted' => 0])
      ->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 = SystemUser::mk()
    ->where(['is_deleted' => 0, 'status' => 1])
    ->cache('user_list', 3600)
    ->select();

// 避免 N+1 查询(使用关联查询)
$users = SystemUser::mk()
    ->with(['userinfo'])
    ->where(['is_deleted' => 0, 'status' => 1])
    ->select();

3. 文件存储优化

实际案例:系统参数配置中的存储管理

<?php
declare(strict_types=1);

namespace app\admin\controller;

use think\admin\Controller;
use think\admin\Storage;
use think\admin\storage\QiniuStorage;
use think\admin\storage\AliossStorage;
use think\admin\storage\TxcosStorage;

class Config extends Controller
{
    /**
     * 系统参数配置
     * @auth true
     * @menu true
     */
    public function index()
    {
        $this->title = '系统参数配置';
        // 获取所有可用的存储类型
        $this->files = Storage::types();
        $this->fetch();
    }
    
    /**
     * 修改文件存储配置
     * @auth true
     */
    public function storage()
    {
        $this->_applyFormToken();
        if ($this->request->isGet()) {
            $this->type = input('type', 'local');
            // 根据存储类型获取区域列表
            if ($this->type === 'alioss') {
                $this->points = AliossStorage::region();
            } elseif ($this->type === 'qiniu') {
                $this->points = QiniuStorage::region();
            } elseif ($this->type === 'txcos') {
                $this->points = TxcosStorage::region();
            }
            $this->fetch("storage-{$this->type}");
        } else {
            $post = $this->request->post();
            // 验证文件扩展名
            if (!empty($post['storage']['allow_exts'])) {
                $deny = ['sh', 'asp', 'bat', 'cmd', 'exe', 'php'];
                $exts = array_unique(str2arr(strtolower($post['storage']['allow_exts'])));
                if (count(array_intersect($deny, $exts)) > 0) {
                    $this->error('禁止上传可执行的文件!');
                }
                $post['storage']['allow_exts'] = join(',', $exts);
            }
            // 保存配置
            foreach ($post as $name => $value) {
                sysconf($name, $value);
            }
            sysoplog('系统配置管理', "修改系统存储参数");
            $this->success('修改文件存储成功!');
        }
    }
}

基础用法:

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

📦 插件开发

1. 插件结构

plugin-name/
├── src/
│   ├── controller/        # 控制器
│   ├── model/             # 模型
│   ├── service/           # 服务类
│   └── view/              # 视图
├── stc/
│   └── database/          # 数据库迁移
├── composer.json          # 插件配置
└── readme.md             # 插件说明

2. 服务注册

<?php
namespace app\admin;

use think\admin\Plugin;

/**
 * 插件服务注册
 * @class Service
 * @package app\admin
 */
class Service extends Plugin
{
    /**
     * 定义插件名称
     * @var string
     */
    protected $appName = '系统管理';

    /**
     * 定义安装包名
     * @var string
     */
    protected $package = 'zoujingli/think-plugs-admin';

    /**
     * 定义插件中心菜单
     * @return array
     */
    public static function menu(): array
    {
        return [
            [
                'name' => '系统配置',
                'subs' => [
                    ['name' => '系统参数配置', 'icon' => 'layui-icon layui-icon-set', 'node' => 'admin/config/index'],
                    ['name' => '系统任务管理', 'icon' => 'layui-icon layui-icon-log', 'node' => 'admin/queue/index'],
                ],
            ],
        ];
    }
}

3. 数据库迁移

<?php
// database/migrations/20241010000001_install_admin20241010.php

use think\migration\Migrator;
use think\migration\db\Column;

class InstallAdmin20241010 extends Migrator
{
    public function change()
    {
        $table = $this->table('system_user', ['comment' => '系统用户表']);
        $table->addColumn('username', 'string', ['limit' => 50, 'comment' => '登录账号'])
              ->addColumn('password', 'string', ['limit' => 32, 'comment' => '登录密码'])
              ->addColumn('nickname', 'string', ['limit' => 50, 'null' => true, 'comment' => '用户昵称'])
              ->addColumn('status', 'integer', ['limit' => 1, 'default' => 1, 'comment' => '状态(0禁用,1启用)'])
              ->addColumn('create_at', 'timestamp', ['null' => true, 'comment' => '创建时间'])
              ->addColumn('update_at', 'timestamp', ['null' => true, 'comment' => '更新时间'])
              ->addIndex(['username'], ['unique' => true])
              ->create();
    }
}

4. 插件配置规范

{
  "type": "think-admin-plugin",
  "name": "zoujingli/think-plugs-admin",
  "version": "1.0.0",
  "license": "MIT",
  "homepage": "https://thinkadmin.top",
  "description": "Admin Plugin for ThinkAdmin",
  "authors": [
    {
      "name": "Anyon",
      "email": "zoujingli@qq.com"
    }
  ],
  "require": {
    "php": ">7.1",
    "ext-json": "*",
    "topthink/framework": "^6.0|^8.0",
    "zoujingli/think-library": "^6.1|@dev"
  },
  "autoload": {
    "psr-4": {
      "app\\admin\\": "src"
    }
  },
  "extra": {
    "config": {
      "type": "module",
      "name": "系统后台管理",
      "document": "https://thinkadmin.top/plugin/think-plugs-admin.html",
      "description": "后台基础管理模块,系统账号及安全配置管理。"
    },
    "plugin": {
      "copy": {
        "stc/database": "database/migrations"
      }
    },
    "think": {
      "services": [
        "app\\admin\\Service"
      ]
    }
  }
}

🧪 测试最佳实践

1. 单元测试

<?php
declare(strict_types=1);

namespace tests;

use PHPUnit\Framework\TestCase;

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

2. 功能测试

<?php
declare(strict_types=1);

namespace tests;

use PHPUnit\Framework\TestCase;
use think\admin\model\SystemUser;

/**
 * 用户管理功能测试
 * @class UserManagementTest
 */
class UserManagementTest extends TestCase
{
    public function testUserManagement()
    {
        // 1. 创建用户
        $user = SystemUser::mk()->save([
            'username' => 'testuser',
            'password' => md5('testuser'),
            'nickname' => '测试用户',
            'status' => 1,
        ]);
        
        // 2. 登录
        $this->login($user);
        
        // 3. 访问用户列表
        $response = $this->get('/admin/user');
        $response->assertSee($user->username);
        
        // 4. 编辑用户
        $response = $this->post('/admin/user/edit', [
            'id' => $user->id,
            'nickname' => '新昵称'
        ]);
        $response->assertStatus(200);
    }
}

📝 代码规范

1. PHP 代码规范

控制器类规范

/**
 * 系统用户管理
 * @class User
 * @package app\admin\controller
 */
class User extends Controller
{
    /**
     * 系统用户管理
     * @auth true
     * @menu true
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function index()
    {
        $this->title = '系统用户管理';
        SystemUser::mQuery()->layTable();
    }
}

严格类型声明

所有 PHP 文件必须使用严格类型声明:

declare(strict_types=1);

2. 权限注解规范

注解类型说明

  • @auth true: 需要权限验证,只有拥有相应权限的用户才能访问
  • @menu true: 添加到系统菜单,会在菜单管理中显示
  • @login true: 需要登录验证,已登录用户即可访问

注解使用示例

/**
 * 系统用户管理
 * @auth true    # 需要权限验证
 * @menu true    # 添加到菜单
 */
public function index()
{
    // 列表页面,需要权限验证并显示在菜单中
}

/**
 * 添加系统用户
 * @auth true    # 需要权限验证
 */
public function add()
{
    // 添加页面,需要权限验证但不显示在菜单中
}

/**
 * 修改用户资料
 * @login true   # 只需要登录即可访问
 */
public function info()
{
    // 个人资料页面,登录用户即可访问
}

3. 注释规范

类注释规范

/**
 * 系统用户管理
 * @class User
 * @package app\admin\controller
 */

方法注释规范

/**
 * 系统用户管理
 * @auth true
 * @menu true
 * @throws \think\db\exception\DataNotFoundException
 * @throws \think\db\exception\DbException
 * @throws \think\db\exception\ModelNotFoundException
 */
public function index()
{
    // 方法实现
}

参数和返回值注释

/**
 * 表单数据处理
 * @param array $data 表单数据(引用传递,可修改)
 * @throws \think\db\exception\DataNotFoundException
 * @throws \think\db\exception\DbException
 * @throws \think\db\exception\ModelNotFoundException
 */
protected function _form_filter(array &$data)
{
    // 方法实现
}

/**
 * 表单结果处理
 * @param bool $status 保存结果
 * @param array $post 提交的数据
 * @return void
 */
protected function _form_result(bool $status, array $post)
{
    // 方法实现
}

🚀 部署最佳实践

1. 生产环境配置

// config/app.php(ThinkPHP 基础配置)
return [
    'app_debug' => false,  // ThinkPHP 调试开关
    'app_trace' => false,  // ThinkPHP 页面追踪
    'log' => [
        'level' => 'error',
        'file_size' => 2097152,
    ],
];

注意app_debug 是 ThinkPHP 的基础调试开关,而 ThinkAdmin 的运行模式(开发模式/生产模式)需要通过后台配置 runtime/.env 文件,详见 运行模式文档

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 system_user(status, create_at);
CREATE INDEX idx_order_user_status ON system_order(user_id, status);

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

查询优化

// 使用分页避免大量数据查询(推荐使用模型方法)
SystemUser::mQuery()->layTable(function () {
    $this->title = '用户管理';
}, function (QueryHelper $query) {
    $query->where(['is_deleted' => 0, 'status' => 1])
          ->order('create_at desc');
});

// 只查询需要的字段
$users = SystemUser::mk()
    ->field('id,username,email,create_at')
    ->where(['is_deleted' => 0, '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);
}

文件缓存

// 缓存配置信息(示例:使用 Db 助手查询配置表)
use think\facade\Db;

$config = $this->app->cache->remember('system_config', function() {
    return Db::name('system_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()]);

🛠️ Helper 助手

1. QueryHelper 查询助手

基本使用

// 列表查询
SystemUser::mQuery()->layTable(function () {
    $this->title = '系统用户管理';
}, function (QueryHelper $query) {
    $query->where(['is_deleted' => 0, 'status' => 1]);
    $query->equal('status,usertype')->dateBetween('login_at,create_at');
    $query->like('username|nickname#username,contact_phone#phone');
});

数据回调处理

// 列表数据后置处理
protected function _index_page_filter(array &$data)
{
    foreach ($data as &$vo) {
        // 对数据进行二次处理
        $vo['custom_field'] = '处理后的值';
    }
}

2. FormHelper 表单助手

基本使用

// 添加/编辑表单
public function add()
{
    SystemUser::mForm('form');
}

public function edit()
{
    SystemUser::mForm('form');
}

表单数据处理

protected function _form_filter(array &$data)
{
    if ($this->request->isGet()) {
        // GET 请求:准备表单数据
        $this->auths = SystemAuth::items();
        $this->bases = SystemBase::items('身份权限');
    } else {
        // POST 请求:处理表单提交
        if (empty($data['username'])) {
            $this->error('登录账号不能为空!');
        }
        // 数据预处理
        $data['authorize'] = arr2str($data['authorize'] ?? []);
    }
}

protected function _form_result(bool $state, array $post)
{
    if ($state && $this->request->post('action') === 'save') {
        // 保存成功后的处理
        $this->success('权限修改成功!', 'javascript:history.back()');
    }
}

3. SaveHelper 保存助手

基本使用

// 修改数据状态
public function state()
{
    SystemUser::mSave($this->_vali([
        'status.in:0,1'  => '状态值范围异常!',
        'status.require' => '状态值不能为空!',
    ]));
}

结果回调处理

protected function _state_save_result(bool $result)
{
    if ($result) {
        $this->success('状态修改成功!');
    } else {
        $this->error('状态修改失败!');
    }
}

4. DeleteHelper 删除助手

基本使用

// 删除数据
public function remove()
{
    $this->_checkInput();
    SystemUser::mDelete();
}

// 检查输入变量
private function _checkInput()
{
    if (in_array('10000', str2arr(input('id', '')))) {
        $this->error('系统超级账号禁止删除!');
    }
}

删除结果处理

protected function _remove_delete_result(bool $result)
{
    if ($result) {
        // 删除成功后的处理
        $this->success('删除成功!');
    } else {
        $this->error('删除失败!');
    }
}

🔧 常见问题解决

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 = SystemUser::mk()
        ->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