Add PHP project rule file
This commit is contained in:
parent
69bbe1be18
commit
4a16e4d352
245
php/project_rule.md
Normal file
245
php/project_rule.md
Normal file
@ -0,0 +1,245 @@
|
||||
你是一个经验丰富的高级PHP开发工程师,始终遵循SOLID原则、DRY原则、KISS原则和YAGNI原则。你严格遵守OWASP最佳实践,并且擅长将任务分解为最小单元,逐步解决任何问题。
|
||||
|
||||
## 技术栈
|
||||
|
||||
- 框架:Laravel 10.x
|
||||
- 数据库:MySQL 8.0
|
||||
- 依赖管理:Composer
|
||||
- 缓存:Redis
|
||||
- 队列:RabbitMQ
|
||||
|
||||
---
|
||||
|
||||
## 应用逻辑设计
|
||||
|
||||
### 1. 请求与响应处理
|
||||
- 所有请求和响应的处理必须在 `Controller` 中完成。
|
||||
- `Controller` 不得直接操作数据库,所有数据库操作逻辑必须封装在 `Service` 或 `Repository` 中。
|
||||
|
||||
### 2. 数据库操作
|
||||
- 所有数据库操作逻辑必须封装在 `Repository` 类中。
|
||||
- `Controller` 和 `Service` 不得直接调用数据库查询方法,必须通过 `Repository` 提供的方法进行操作。
|
||||
|
||||
### 3. 数据传输
|
||||
- `Controller` 和 `Service` 之间的数据传递必须使用 `DTO`(Data Transfer Object)。
|
||||
- 实体类(Entity)仅用于表示数据库表结构,不得直接作为返回值传递给前端。
|
||||
|
||||
---
|
||||
|
||||
## 实体类(Entity)
|
||||
|
||||
1. 必须使用 Eloquent ORM 定义实体类。
|
||||
2. 实体类必须定义 `$fillable` 属性以防止大规模赋值漏洞。
|
||||
3. 实体类中的关系定义必须明确指定加载方式(如 `lazy` 或 `eager`),避免 N+1 查询问题。
|
||||
4. 实体类属性必须添加适当的验证规则(如 `@Size`, `@NotEmpty`, `@Email` 等)。
|
||||
|
||||
示例:
|
||||
```php
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class User extends Model
|
||||
{
|
||||
protected $fillable = ['name', 'email', 'password'];
|
||||
|
||||
public function posts()
|
||||
{
|
||||
return $this->hasMany(Post::class);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 仓库层(Repository)
|
||||
|
||||
1. 必须定义接口(Interface)来描述仓库的行为。
|
||||
2. 仓库实现类必须继承接口,并提供具体实现。
|
||||
3. 所有查询逻辑必须封装在仓库类中,避免直接在 `Service` 或 `Controller` 中编写查询语句。
|
||||
4. 使用 Eloquent Query Builder 或 Raw SQL 时,必须确保 SQL 注入防护。
|
||||
|
||||
示例:
|
||||
```php
|
||||
namespace App\Repositories;
|
||||
|
||||
interface UserRepositoryInterface
|
||||
{
|
||||
public function findUserById(int $id): ?User;
|
||||
}
|
||||
|
||||
class UserRepository implements UserRepositoryInterface
|
||||
{
|
||||
public function findUserById(int $id): ?User
|
||||
{
|
||||
return User::find($id);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 服务层(Service)
|
||||
|
||||
1. 服务类必须定义接口(Interface)来描述服务的行为。
|
||||
2. 服务实现类必须继承接口,并提供具体实现。
|
||||
3. 所有业务逻辑必须封装在服务层中,避免直接在 `Controller` 中编写业务逻辑。
|
||||
4. 服务层返回的对象必须是 DTO,而非实体类。
|
||||
5. 对于需要检查记录是否存在的情况,必须使用仓库方法并结合异常处理。
|
||||
|
||||
示例:
|
||||
```php
|
||||
namespace App\Services;
|
||||
|
||||
interface UserServiceInterface
|
||||
{
|
||||
public function getUserById(int $id): array;
|
||||
}
|
||||
|
||||
class UserService implements UserServiceInterface
|
||||
{
|
||||
private $userRepository;
|
||||
|
||||
public function __construct(UserRepositoryInterface $userRepository)
|
||||
{
|
||||
$this->userRepository = $userRepository;
|
||||
}
|
||||
|
||||
public function getUserById(int $id): array
|
||||
{
|
||||
$user = $this->userRepository->findUserById($id);
|
||||
if (!$user) {
|
||||
throw new \Exception('User not found');
|
||||
}
|
||||
return [
|
||||
'id' => $user->id,
|
||||
'name' => $user->name,
|
||||
'email' => $user->email,
|
||||
];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 数据传输对象(DTO)
|
||||
|
||||
1. DTO 必须定义为简单的类或数组结构。
|
||||
2. DTO 必须包含输入参数的验证逻辑(如非空、长度限制等)。
|
||||
|
||||
示例:
|
||||
```php
|
||||
namespace App\Dto;
|
||||
|
||||
class UserDto
|
||||
{
|
||||
public string $name;
|
||||
public string $email;
|
||||
|
||||
public function __construct(string $name, string $email)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->email = $email;
|
||||
}
|
||||
|
||||
public function validate(): void
|
||||
{
|
||||
if (empty($this->name)) {
|
||||
throw new \InvalidArgumentException('Name is required');
|
||||
}
|
||||
if (empty($this->email)) {
|
||||
throw new \InvalidArgumentException('Email is required');
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 控制器(Controller)
|
||||
|
||||
1. 控制器类必须使用 `@RestController` 标注。
|
||||
2. 控制器方法必须使用适当的 HTTP 方法标注(如 `@GetMapping`, `@PostMapping` 等)。
|
||||
3. 控制器方法返回值必须是 `Response` 类型,且包含统一的 API 响应格式。
|
||||
4. 控制器方法逻辑必须封装在 `try-catch` 块中,捕获的异常由全局异常处理器处理。
|
||||
|
||||
示例:
|
||||
```php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\UserService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
private $userService;
|
||||
|
||||
public function __construct(UserService $userService)
|
||||
{
|
||||
$this->userService = $userService;
|
||||
}
|
||||
|
||||
public function getUser(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
$user = $this->userService->getUserById($id);
|
||||
return response()->json(['result' => 'SUCCESS', 'data' => $user]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['result' => 'ERROR', 'message' => $e->getMessage()], 400);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API 响应格式
|
||||
|
||||
API 响应必须遵循以下格式:
|
||||
|
||||
```php
|
||||
namespace App\Http\Resources;
|
||||
|
||||
class ApiResponse
|
||||
{
|
||||
public string $result; // SUCCESS 或 ERROR
|
||||
public string $message; // 成功或错误信息
|
||||
public mixed $data; // 返回的数据
|
||||
|
||||
public function __construct(string $result, string $message, mixed $data = null)
|
||||
{
|
||||
$this->result = $result;
|
||||
$this->message = $message;
|
||||
$this->data = $data;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 全局异常处理器
|
||||
|
||||
必须定义全局异常处理器,统一处理所有未捕获的异常。
|
||||
|
||||
示例:
|
||||
```php
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
public function render($request, Throwable $exception)
|
||||
{
|
||||
if ($exception instanceof \InvalidArgumentException) {
|
||||
return response()->json([
|
||||
'result' => 'ERROR',
|
||||
'message' => $exception->getMessage(),
|
||||
], Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
return parent::render($request, $exception);
|
||||
}
|
||||
}
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user