PHP 项目团队协作规范
代码规范
1 PSR 标准遵循
- 必须遵循 PSR-1(基础编码规范)和 PSR-12(扩展编码规范)
- 推荐使用 PSR-4 自动加载标准
- 统一 PHP 版本(如 PHP 8.1+),禁止使用废弃函数
2 命名规范
| 类型 | 规范 | 示例 |
|---|---|---|
| 类名 | 大驼峰(StudlyCase) | UserService |
| 方法名 | 小驼峰(camelCase) | getUserList() |
| 变量名 | 小驼峰或蛇形 | $userName / $user_data(选其一,团队统一) |
| 常量 | 大写+下划线 | MAX_RETRY_COUNT |
| 数组键 | 蛇形(推荐) | ['user_name' => '张三'] |
| 文件名 | 大驼峰(类文件) | UserService.php |
| 数据库表 | 复数蛇形 | users、order_items |
| 数据库字段 | 蛇形 | created_at |
3 代码风格要求
- 缩进统一使用 4个空格(不使用 Tab)
- 单行代码不超过 120字符
- 每个 PHP 文件 必须以
<?php开头,文件末尾 不保留闭合标签?> - 类的大括号须另起一行(PSR-12),控制结构的大括号与关键字同行
- 不使用
echo输出 HTML(应使用模板引擎)
<?php
declare(strict_types=1);
namespace App\Services;
use App\Repositories\UserRepository;
class UserService
{
private UserRepository $repository;
public function __construct(UserRepository $repository)
{
$this->repository = $repository;
}
public function getUserList(): array
{
$users = $this->repository->findAll();
// 注释风格:解释"为什么",而非"是什么"
return array_map(function (array $user): array {
return [
'id' => (int) $user['id'],
'user_name' => $user['user_name'],
];
}, $users);
}
}
版本控制(Git Flow)
1 分支模型
main ├── 生产环境代码(受保护,不可直接推送)
hotfix/* ├── 紧急修复(从 main 检出,修复后合并回 main 和 develop)
release/* ├── 发布准备(从 develop 检出,合并回 main 和 develop)
develop ├── 日常集成(受保护,不可直接推送)
feature/* ├── 新功能开发(从 develop 检出,合并回 develop)
└── 示例:feature/user-login
2 提交规范(Conventional Commits)
| 类型 | 说明 | 示例 |
|---|---|---|
| feat | 新功能 | feat: add user registration endpoint |
| fix | 修复 Bug | fix: resolve null pointer exception in order module |
| docs | 文档变更 | docs: update README with API examples |
| style | 格式调整 | style: format code with php-cs-fixer |
| refactor | 代码重构 | refactor: extract payment logic to service class |
| test | 测试相关 | test: add unit tests for UserService |
| chore | 构建/工具 | chore: update composer dependencies |
| perf | 性能优化 | perf: add Redis cache for hot product queries |
| revert | 回滚提交 | revert: revert commit 2a3f4b5 |
格式:
<type>(<scope>): <subject>
示例:
feat(order): add order cancellation API
- 新增订单取消接口
- 增加取消原因记录
- 补充单元测试
Refs: #123
3 Code Review 流程
- 所有代码合并到
develop必须通过 Pull Request(或 Merge Request) - PR 至少 1-2 人 审查通过后方可合并
- PR 需关联任务/缺陷编号
- Review 重点:代码质量、逻辑正确性、安全漏洞、是否符合规范
环境与依赖管理
1 开发环境标准化
- 使用 Docker 统一开发环境(统一 PHP 版本、扩展、服务版本)
- 推荐使用 Laravel Sail 或 Docker Compose 搭建开发环境
- PHP 版本、Composer 版本、扩展列表须在
README.md中明确记录
2 Composer 依赖管理
- 所有依赖必须通过
composer.json管理 - 生产依赖(
require)与 开发依赖(require-dev)严格区分 - 提交
composer.lock到 Git 仓库,确保生产安装一致 - 新增依赖须在 PR 中说明理由
测试规范
1 测试分层与覆盖目标
| 层级 | 技术要求 | 特点 | 覆盖目标 |
|---|---|---|---|
| 单元测试 | PHPUnit | 模拟外部依赖、不访问数据库 | Service/Utility 类 ≥ 80% |
| 集成测试 | PHPUnit + TestCase | 使用独立测试数据库 | Repository/ORM 模型 ≥ 70% |
| 接口测试 | Pest 或 PHPUnit | 模拟 HTTP 请求,使用独立测试数据库 | Controller 核心接口 ≥ 90% |
| E2E 测试 | Playwright(可选) | 完整用户流程 | 核心业务链路 100% |
| 静态分析 | PHPStan / Psalm | 不运行代码 | 严格级别 ≥ 6 |
| 代码风格 | PHP-CS-Fixer | 自动格式化 | PSR-12 100% |
| 安全审计 | 依赖漏洞扫描(如 composer audit) |
检查依赖安全 | 零高危漏洞 |
2 测试命名和结构
目录结构:
tests/
├── Unit/ # 单元测试
│ └── Services/
│ └── UserServiceTest.php
├── Integration/ # 集成测试
│ └── Repositories/
│ └── UserRepositoryTest.php
└── Feature/ # 接口测试(Laravel 惯例)
└── UserApiTest.php
命名约定: 测试方法用下划线或小驼峰描述行为,推荐形式:

// 推荐行为驱动风格
public function test_user_can_register_with_valid_data(): void
{
// Arrange(准备数据)
// Act(执行操作)
// Assert(断言结果)
}
3 覆盖率要求
- 新代码行覆盖率 ≥ 80%
- 关键业务逻辑(支付、权限、数据处理)覆盖率 ≥ 90%
- 使用
phpunit --coverage-html ./coverage生成报告
4 CI 自动化
- 每次 PR 必须通过 CI 全部检查(GitHub Actions / GitLab CI 均可)
# .github/workflows/ci.yml 示例
name: CI
on: [push, pull_request]
jobs:
php-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
coverage: xdebug
- run: composer install --prefer-dist --no-interaction
- run: cp .env.ci .env
- run: php artisan key:generate
- run: vendor/bin/phpunit
- run: vendor/bin/phpstan analyse --memory-limit=512M
- run: vendor/bin/php-cs-fixer fix --dry-run --diff
数据库规范
1 迁移(Migration)
- 所有表结构变更必须通过迁移文件完成,禁止手动修改数据库
- 迁移文件名清晰描述用途:
2024_01_15_100000_add_status_to_orders_table.php - 每个迁移只做一件事
- 生产环境数据变更(数据修复、大批量更新)用独立数据迁移(如 Laravel 的
db:seed或专门的数据迁移类)
2 索引设计
// 推荐使用迁移内建方法管理索引
Schema::table('orders', function (Blueprint $table) {
$table->index('user_id'); // 查询频繁字段
$table->unique('order_no'); // 业务唯一字段
$table->index(['status', 'created_at']); // 复合索引
});
索引设计三个"必须":
- 所有外键必须建立索引
- 高频查询条件必须建立索引
- 复合索引必须遵守最左前缀原则
3 软删除与审计字段
- 核心业务表必须包含
created_at、updated_at审计字段 - 需要保留历史数据的表使用
deleted_at软删除(Laravel 的SoftDeletestrait) - 关键表可增加
created_by、updated_by记录操作人
4 SQL 规范
- 禁止在循环中执行 SQL(N+1 问题),使用 eager loading(
with()) - 复杂查询使用查询构造器或 ORM,禁止拼接原生 SQL
- 大量数据操作用
chunk()分批处理
安全规范
1 输入验证
- 所有用户输入必须经过验证
- 禁止直接拼接用户输入到 SQL 语句(使用预处理语句)
- 文件上传严格校验类型、大小、内容
2 输出转义
- 视图层输出使用模板引擎的自动转义(Blade 的 )
- 禁止直接输出用户提交的 HTML 内容
3 认证与授权
- 使用框架内置认证机制(Laravel Sanctum / JWT)
- 接口必须实现权限控制(RBAC 或策略类)
- 敏感操作记录操作日志
4 敏感数据保护
- 密码使用
password_hash(),禁止明文或 MD5 .env文件中的密钥严禁提交到 Git- API 密钥、数据库密码存于环境变量或密钥管理服务
日志与监控
1 日志规范
- 使用统一日志格式(JSON 结构化推荐)
- 日志级别使用规范:
debug:调试信息(仅开发环境)info:常规操作记录notice:正常但重要事件warning:出现异常但未影响功能error:需要关注的错误critical:系统关键功能不可用
- 关键业务操作必须记录日志(订单创建、支付回调、用户注册等)
// 推荐方式
Log::channel('daily')->info('Order created', [
'order_id' => $order->id,
'user_id' => $order->user_id,
'amount' => $order->amount,
]);
2 错误监控
- 部署 Sentry 或同类错误监控系统
- 生产环境关闭
display_errors,记录日志而非输出
文档规范
1 README 必需内容
- 项目简介与功能架构图
- 环境要求(PHP 版本、扩展、服务)
- 安装步骤(克隆、安装依赖、配置环境、初始化数据库)
- 常用命令(启动、测试、代码格式化)
- 目录结构说明
- API 文档地址或说明
2 API 文档
- 使用 OpenAPI(Swagger) 或 Postman 维护 API 文档
- 接口变更必须同步更新文档
- 每个接口注明:请求方法、路径、参数、返回示例、错误码
3 代码内注释
- 复杂类、方法必须写 PHPDoc
- 注释说明意图而非机械重复代码
- 使用
@param、@return、@throws标注
部署流程
1 发布流程
feature/* → develop(开发集成) → release/*(发布准备) → main(生产)
↓ ↓
(自动测试) (灰度验证/手动测试)
2 部署清单
- [ ] 单元/集成测试全部通过
- [ ] PHPStan/Psalm 静态分析通过
- [ ] 代码风格检查通过
- [ ] 依赖安全检查通过
- [ ] 迁移文件已生成并测试
- [ ] 环境变量配置已更新
- [ ] 文档已同步更新
- [ ] 版本号已更新(遵循语义化版本)
3 发布要求
- 每次发布必须打 Git Tag(如
v1.2.0) - 紧急修复走
hotfix/*分支,禁止直接在 main 修改 - 数据库迁移在生产环境执行前必须在预发布环境演练
沟通与协作流程
1 每日站会
- 每人汇报:昨日完成、今日计划、遇到的阻塞
- 时间控制在 15 分钟内
2 代码评审
- 提交 PR 时附上变更说明
- 评审人在 24 小时内完成评审
- 争议问题:在评审中解决,避免私下争论
3 任务管理
- 使用 Jira / 禅道 / Trello 等项目管理工具
- 任务状态:
待处理 → 开发中 → 测试中 → 已完成 - 每个任务关联代码提交记录
十一、常用工具配置
1 PHP-CS-Fixer 配置(.php-cs-fixer.php)
<?php
return (new PhpCsFixer\Config())
->setRules([
'@PSR-12' => true,
'array_syntax' => ['syntax' => 'short'],
'no_unused_imports' => true,
'ordered_imports' => ['sort_algorithm' => 'alpha'],
'single_quote' => true,
'trailing_comma_in_multiline' => true,
])
->setFinder(
PhpCsFixer\Finder::create()
->in(['app', 'routes', 'tests', 'database'])
);
2 PHPStan 配置(phpstan.neon)
parameters:
level: 6
paths:
- app
- tests
tmpDir: storage/framework/cache/phpstan
3 自动化 Githook
# .git/hooks/pre-commit(示例)
#!/bin/sh
if [ -f "vendor/bin/php-cs-fixer" ]; then
vendor/bin/php-cs-fixer fix --dry-run --diff src/
if [ $? -ne 0 ]; then
echo "❌ 代码风格检查未通过,请先运行 php-cs-fixer fix"
exit 1
fi
fi
if [ -f "vendor/bin/phpstan" ]; then
vendor/bin/phpstan analyse
if [ $? -ne 0 ]; then
echo "❌ 静态分析未通过"
exit 1
fi
fi
exit 0
十二、常见痛点与解决方案
| 常见问题 | 解决方案 |
|---|---|
| 每个人的代码风格不统一 | 强制使用 PHP-CS-Fixer + pre-commit 钩子 |
| 数据库结构混乱 | 所有变更走迁移,禁止手动修改 |
| 测试环境不一致 | 使用 Docker 统一环境 |
| 合并冲突频繁 | 小步提交(每次功能独立分支)、频繁合并 develop |
| 安全漏洞被忽视 | 定期 composer audit + 依赖自动更新检查 |
| 代码走查流于形式 | 走查清单化(安全、性能、可读性、测试) |
快速参考命令
# 安装依赖 composer install # 运行测试 vendor/bin/phpunit # 静态分析 vendor/bin/phpstan analyse # 代码格式化 vendor/bin/php-cs-fixer fix # 创建迁移 php artisan make:migration create_users_table # 执行迁移 php artisan migrate # 代码检查(一键组合) composer check-all
规范可根据团队实际技术栈(Laravel / Symfony / ThinkPHP 等)和项目规模进行调整,核心原则是:自动化、一致性、可追溯、持续改进,建议在项目启动时与全体成员一起讨论确认,形成团队共识后严格执行。