Cursor + PHP + Yii2 Backend Skill 完整的 Cursor Agent 配置

这套配置的目标是让 Cursor 不只是“会写 Yii2”,而是按后端工程师的方式分析、修改、测试和 Review Yii2 项目。

Cursor + PHP + Yii2 Backend Skill

目录结构

.cursor/
├── rules/
│   ├── php.mdc
│   ├── yii2.mdc
│   ├── mysql.mdc
│   ├── redis.mdc
│   ├── api.mdc
│   ├── security.mdc
│   └── testing.mdc
│
└── skills/
    └── yii2-backend/
        ├── SKILL.md
        └── references/
            ├── architecture.md
            ├── database.md
            └── review.md

1. .cursor/rules/php.mdc

---
description: PHP backend development standards
globs:
  - "**/*.php"
alwaysApply: true
---

# PHP Development Rules

## PHP Version

Before writing new PHP code:

1. Inspect composer.json.
2. Determine the project's PHP version.
3. Follow the project's existing PHP syntax and conventions.
4. Do not introduce syntax unsupported by the project's PHP version.

## Type Safety

Prefer:

- strict parameter types
- return types
- nullable types
- typed properties
- enums when supported by the project

Avoid unnecessary mixed values.

Example:

GOOD:

```php
public function getUser(int $id): ?User
{
    return User::findOne($id);
}

Avoid:

public function getUser($id)
{
    return User::findOne($id);
}

unless the existing project intentionally follows weak typing.

Error Handling

Do not silently swallow exceptions.

Bad:

try {
    // ...
} catch (\Throwable $e) {
}

If an exception must be caught:

  • log it
  • add meaningful context
  • either recover or rethrow

Null Handling

Do not assume database queries always return records.

Bad:

$user = User::findOne($id);

return $user->name;

Prefer:

$user = User::findOne($id);

if ($user === null) {
    throw new NotFoundHttpException('User not found.');
}

Code Duplication

Before adding a new helper:

  1. Search the project.
  2. Check whether the functionality already exists.
  3. Reuse existing abstractions when appropriate.

Do not create unnecessary utility classes.

Backward Compatibility

When modifying existing code:

  • preserve existing public method signatures when possible
  • preserve API response formats
  • preserve database behavior
  • avoid unnecessary refactoring
  • avoid changing unrelated files

Dependency Policy

Do not add Composer packages automatically.

Before adding a dependency:

  1. Check whether the project already has equivalent functionality.
  2. Check composer.json.
  3. Explain why the dependency is necessary.
  4. Prefer Yii2/PHP standard functionality when sufficient.

---

# 2. `.cursor/rules/yii2.mdc`

```md
---
description: Yii2 framework architecture and development rules
globs:
  - "**/*.php"
alwaysApply: true
---

# Yii2 Development Rules

## Architecture

Prefer:

Controller
    ↓
Service
    ↓
Model / ActiveRecord
    ↓
Database

Controllers should remain thin.

Controllers are responsible for:

- receiving HTTP parameters
- authentication
- authorization
- request validation
- calling services
- formatting responses

Controllers should NOT contain complex business logic.

## Controller

Avoid:

```php
public function actionCreate()
{
    $model = new Order();

    if ($model->load(Yii::$app->request->post())) {
        // hundreds of lines of business logic
    }
}

Prefer:

public function actionCreate()
{
    $params = Yii::$app->request->post();

    $order = $this->orderService->create($params);

    return $order;
}

Service

Use services for:

  • business workflows
  • transactions
  • cross-model operations
  • external API calls
  • complex business rules
  • queue dispatch
  • multi-step operations

Example:

final class OrderService
{
    public function create(array $params): Order
    {
        return Yii::$app->db->transaction(function () use ($params) {
            // business logic
        });
    }
}

ActiveRecord

Use ActiveRecord for:

  • entity persistence
  • simple queries
  • relationships
  • validation

Avoid putting large business workflows inside ActiveRecord.

ActiveQuery

Prefer readable queries:

Order::find()
    ->where(['status' => Order::STATUS_PENDING])
    ->orderBy(['id' => SORT_DESC])
    ->all();

N+1 Prevention

Always check for N+1 when using relations.

Potentially dangerous:

$orders = Order::find()->all();

foreach ($orders as $order) {
    echo $order->user->name;
}

Prefer:

$orders = Order::find()
    ->with('user')
    ->all();

When modifying relationship-heavy code, inspect the generated SQL if necessary.

Large Dataset

Never blindly use:

Model::find()->all();

for potentially large datasets.

Prefer:

foreach (
    Model::find()->batch(500) as $models
) {
    foreach ($models as $model) {
        // ...
    }
}

or:

foreach (
    Model::find()->each(500) as $model
) {
    // ...
}

updateAll/deleteAll

For large bulk operations consider:

Model::updateAll(
    ['status' => Model::STATUS_DONE],
    ['status' => Model::STATUS_PENDING]
);

and:

Model::deleteAll([
    'status' => Model::STATUS_DELETED,
]);

But check:

  • events
  • behaviors
  • timestamps
  • business rules

because bulk operations bypass normal ActiveRecord lifecycle behavior.

Transactions

Use transactions when multiple writes must succeed or fail together.

Yii::$app->db->transaction(function () {
    // write A
    // write B
});

Do not create unnecessary long transactions.

Do not hold database transactions while waiting for:

  • HTTP requests
  • external APIs
  • long-running jobs
  • user input

Validation

Never trust HTTP input.

Use:

  • rules()
  • scenarios
  • explicit validation
  • typed DTOs when appropriate

Do not blindly persist:

$model->load($request->post());
$model->save();

without checking validation result.

Dependency Injection

For new code prefer dependency injection where practical.

Avoid unnecessary:

Yii::$app->someComponent

inside deeply nested business logic.

Use constructor injection for stable dependencies when compatible with the project architecture.

Existing Project Conventions

Before creating a new class:

  1. Search similar classes.
  2. Follow existing namespace conventions.
  3. Follow existing directory structure.
  4. Follow existing naming conventions.
  5. Reuse existing base classes.

---

# 3. `.cursor/rules/mysql.mdc`

```md
---
description: MySQL database development and performance rules
globs:
  - "**/*.php"
  - "**/*.sql"
alwaysApply: true
---

# MySQL Rules

## Query Safety

Never concatenate user input into SQL.

Bad:

```php
$sql = "SELECT * FROM user WHERE name = '" . $name . "'";

Use parameterized queries.

Query Performance

When modifying database code, consider:

  1. indexes
  2. WHERE conditions
  3. ORDER BY
  4. JOIN
  5. GROUP BY
  6. LIMIT
  7. result size
  8. N+1 queries

Indexes

Before adding an index:

  • inspect existing indexes
  • check query patterns
  • avoid duplicate indexes
  • consider composite index ordering

Do not add indexes blindly.

N+1

Always inspect loops containing database queries.

Bad:

foreach ($orders as $order) {
    User::findOne($order->user_id);
}

Prefer eager loading or batch querying.

Large Data

Avoid:

->all()

for millions of records.

Prefer:

  • batch()
  • each()
  • pagination
  • cursor-like processing where appropriate

COUNT

Be careful with expensive COUNT queries on large tables.

Transactions

Keep transactions short.

Never perform slow external HTTP requests inside database transactions unless absolutely necessary.

SQL Review

For complex queries, consider using:

EXPLAIN

before recommending a performance optimization.

Never claim a query is optimized without examining its execution characteristics when performance is the actual task.


---

# 4. `.cursor/rules/redis.mdc`

```md
---
description: Redis caching, locking and queue rules
globs:
  - "**/*.php"
alwaysApply: true
---

# Redis Rules

## Key Naming

Redis keys must have a consistent namespace.

Prefer:

```text
project:user:{id}
project:order:{id}
project:lock:order:{id}

Avoid random key formats.

Cache

Every cache entry must consider:

  • key
  • TTL
  • invalidation
  • serialization
  • stampede protection

Do not cache everything.

Cache Stampede

For hot data consider:

  • locking
  • early refresh
  • stale-while-revalidate
  • randomized TTL

Distributed Lock

When using Redis locks:

  • always define TTL
  • always release the lock
  • avoid infinite locks
  • make operations idempotent

Example conceptual pattern:

acquire lock
    ↓
execute
    ↓
finally release lock

Queue

Queue jobs must be:

  • idempotent
  • retry-safe
  • timeout-aware
  • failure-aware

Do not assume a job executes exactly once.

Retry

When implementing retries consider:

  • transient errors
  • permanent errors
  • retry count
  • backoff
  • dead-letter/failed queue

Redis Memory

Do not store unlimited collections.

Consider:

  • TTL
  • maximum list size
  • maximum set size
  • memory usage

---

# 5. `.cursor/rules/api.mdc`

```md
---
description: Yii2 REST API development rules
globs:
  - "**/controllers/**/*.php"
  - "**/modules/**/*.php"
alwaysApply: true
---

# API Rules

## Input

Never trust request input.

Validate:

- required fields
- type
- length
- range
- enum
- authorization

## Response

API responses should follow the project's existing response format.

Do not introduce a new response structure without checking existing APIs.

## HTTP Status

Use appropriate status codes when the project supports them:

200 - success
201 - created
204 - no content
400 - invalid request
401 - unauthenticated
403 - unauthorized
404 - not found
409 - conflict
422 - validation error
500 - server error

## Authentication

Authentication and authorization are different.

Always check authorization for resources.

Example:

User A must not be able to access User B's resource simply by changing:

```text
?id=123

Pagination

For potentially large API results use pagination.

Do not return unlimited database records.

Serialization

Do not blindly return ActiveRecord objects if that may expose:

  • password hashes
  • tokens
  • internal IDs
  • internal status
  • sensitive fields

Use explicit fields when appropriate.

API Compatibility

Before changing:

  • field names
  • response structure
  • HTTP status
  • error format

search existing frontend/client usage.


---

# 6. `.cursor/rules/security.mdc`

```md
---
description: PHP Yii2 security rules
globs:
  - "**/*.php"
alwaysApply: true
---

# Security Rules

Every new backend feature must consider:

- authentication
- authorization
- input validation
- SQL injection
- XSS
- CSRF
- IDOR
- mass assignment
- file upload
- SSRF
- command injection
- sensitive information exposure
- logging of secrets

## SQL Injection

Never concatenate user-controlled SQL.

## Mass Assignment

Do not blindly assign:

```php
$model->attributes = $request->post();

without checking Yii2 safe attributes and validation.

IDOR

Never assume an authenticated user can access a resource.

Bad:

$order = Order::findOne($id);

if authorization is not checked.

Prefer checking ownership or RBAC.

Passwords

Never:

  • log passwords
  • return password hashes
  • put secrets into source code

Tokens

Never log:

  • JWT
  • access token
  • refresh token
  • API key
  • session cookie

File Upload

Validate:

  • extension
  • MIME type
  • file size
  • filename
  • storage location

Do not trust the uploaded filename.

Command Execution

Be extremely careful with:

exec()
shell_exec()
system()
passthru()

Never pass untrusted user input directly into shell commands.

External URL

Validate external URLs before making server-side HTTP requests.

Consider SSRF.

Logging

Logs should contain enough information for debugging but must not contain secrets or sensitive user data.


---

# 7. `.cursor/rules/testing.mdc`

```md
---
description: PHP Yii2 testing rules
globs:
  - "**/*.php"
alwaysApply: true
---

# Testing Rules

When modifying business logic:

1. Identify existing tests.
2. Add or update tests when practical.
3. Run the relevant test suite.
4. Do not claim tests pass unless they were actually executed.

## Unit Tests

Prioritize:

- business rules
- services
- complex calculations
- permission checks
- edge cases

## API Tests

Test:

- successful request
- invalid parameters
- unauthorized request
- nonexistent resource
- boundary conditions

## Database Tests

When database behavior matters, test:

- insert
- update
- transaction rollback
- unique constraints
- relations

## Regression

When fixing a bug:

1. reproduce the bug
2. create a regression test
3. implement the fix
4. run the test
5. run related tests

## Test Claims

Never say:

"All tests pass."

unless tests were actually executed.

8. .cursor/skills/yii2-backend/SKILL.md

---
name: yii2-backend
description: Expert PHP Yii2 backend development skill. Use for Yii2 architecture, ActiveRecord, ActiveQuery, REST APIs, services, database operations, Redis, performance optimization, security, debugging, refactoring and backend code review.
---

# Yii2 Backend Expert

You are an experienced PHP/Yii2 backend engineer.

Your job is not merely to generate code.

Before changing code, understand the existing project architecture and conventions.

## Workflow

For every non-trivial task:

### Step 1: Understand the project

Inspect:

- composer.json
- config/
- common/
- frontend/
- backend/
- console/
- api/
- modules/
- models/
- services/
- components/
- behaviors/

Do not assume the project follows the standard Yii2 structure.

### Step 2: Search existing implementation

Before creating new code search for:

- similar Controller
- similar Model
- similar Service
- existing helper
- existing component
- existing Redis wrapper
- existing HTTP client
- existing response formatter
- existing validation rules

Prefer reuse over duplication.

### Step 3: Understand data flow

Determine:

```text
Request
 ↓
Controller
 ↓
Validation
 ↓
Service
 ↓
Model
 ↓
Database

or the actual architecture used by the project.

Step 4: Implement minimum necessary changes

Do not refactor unrelated code.

Avoid changing:

  • unrelated formatting
  • unrelated classes
  • dependency versions
  • database schema

unless required.


Yii2 ActiveRecord

Before modifying ActiveRecord code check:

  • rules()
  • scenarios()
  • relations()
  • behaviors()
  • events
  • beforeSave()
  • afterSave()
  • beforeDelete()
  • afterDelete()

Remember:

updateAll()
deleteAll()

do not behave exactly like individual ActiveRecord save/delete operations.


Query Optimization

When the task involves performance:

  1. inspect SQL
  2. identify query count
  3. identify N+1
  4. inspect indexes
  5. consider eager loading
  6. consider batch processing
  7. consider caching
  8. consider database execution plans

Do not optimize based solely on intuition.


Large Dataset

For large tables prefer:

->batch(500)

or:

->each(500)

instead of:

->all()

Do not load millions of records into PHP memory.


Business Transactions

If a business operation modifies multiple related records:

Yii::$app->db->transaction(function () {
    // operation
});

Keep transaction scope small.

Do not perform external network calls inside transactions unless necessary.


API Development

When creating an API:

  1. inspect existing API conventions
  2. validate input
  3. authenticate
  4. authorize
  5. execute business logic
  6. return consistent response
  7. avoid exposing sensitive fields

Debugging

When debugging:

  1. reproduce
  2. inspect stack trace
  3. identify first meaningful error
  4. inspect surrounding code
  5. check configuration
  6. check database/Redis/external dependencies
  7. propose root cause
  8. implement minimal fix
  9. test

Do not blindly patch the last exception line.


Performance

When asked to optimize:

First establish the bottleneck.

Possible bottlenecks:

  • MySQL
  • Redis
  • PHP CPU
  • PHP memory
  • network
  • external API
  • serialization
  • filesystem
  • queue
  • locking

Do not automatically add Redis caching.


Security

Every change must consider:

  • SQL injection
  • XSS
  • CSRF
  • IDOR
  • RBAC
  • mass assignment
  • file upload
  • SSRF
  • command injection
  • secret leakage

Code Review

When reviewing code, check:

Correctness

  • business logic
  • edge cases
  • null handling
  • concurrency

Database

  • N+1
  • indexes
  • transaction scope
  • unnecessary queries
  • large dataset handling

Performance

  • loops
  • memory
  • caching
  • Redis
  • external requests

Security

  • authorization
  • validation
  • injection
  • sensitive information

Maintainability

  • naming
  • duplication
  • complexity
  • coupling

Compatibility

  • existing API
  • existing database schema
  • existing callers

Response Format

For implementation tasks:

  1. Explain the root cause or approach briefly.
  2. Show the changed files.
  3. Provide complete relevant code.
  4. Explain important design decisions.
  5. Provide test commands.
  6. Clearly state what was actually tested.

Do not claim commands were executed unless they were actually executed.


Important Rule

Do not blindly follow the user's proposed implementation if it introduces:

  • security vulnerabilities
  • data corruption risk
  • obvious performance problems
  • broken Yii2 conventions

Instead explain the problem and provide a safer implementation.


---

# 9. `.cursor/skills/yii2-backend/references/architecture.md`

```md
# Yii2 Architecture Reference

Recommended default architecture:

Controller
    ↓
Request/DTO
    ↓
Service
    ↓
Domain/Model
    ↓
Repository/ActiveRecord
    ↓
Database

However, do not force this architecture onto an existing project.

Existing architecture always takes priority.

## Controller

Responsibilities:

- HTTP
- authentication
- authorization
- parameter extraction
- validation
- response

Avoid business logic.

## Service

Responsibilities:

- business workflow
- transaction
- multiple model coordination
- external service interaction
- queue dispatch

## Model

Responsibilities:

- data representation
- validation
- relationships
- persistence

Avoid putting huge business workflows into models.

## Repository

Do not introduce Repository classes automatically.

Use them when:

- query complexity is high
- data access must be abstracted
- multiple data sources exist
- existing project architecture already uses repositories

Do not create:

Controller → Repository → ActiveRecord

just for the sake of patterns.

## Transaction

Transaction should surround the atomic business operation.

Avoid:

transaction {
    HTTP request
    database operation
}

Prefer:

HTTP request

↓

validate

↓

external preparation if needed

↓

transaction {
    database writes
}

↓

response

10. .cursor/skills/yii2-backend/references/database.md

# Yii2 Database Reference

## Query Checklist

When reviewing a query ask:

1. How many SQL statements execute?
2. Is there N+1?
3. Are indexes available?
4. Is ORDER BY indexed?
5. Is the result set bounded?
6. Is the query executed inside a loop?
7. Is the same query repeated?
8. Can eager loading help?
9. Can batch processing help?
10. Is caching appropriate?

## Common Bad Pattern

```php
foreach ($users as $user) {
    $orders = Order::find()
        ->where(['user_id' => $user->id])
        ->all();
}

Potential N+1.

Better

Use eager loading:

$users = User::find()
    ->with('orders')
    ->all();

or fetch data in batches depending on the use case.

Large Data

Bad:

$rows = Order::find()->all();

Potentially dangerous for large tables.

Better:

foreach (Order::find()->batch(1000) as $orders) {
    // process
}

Bulk Update

Order::updateAll(
    ['status' => Order::STATUS_DONE],
    ['status' => Order::STATUS_PENDING]
);

Remember that ActiveRecord events and behaviors may not run as with individual save() calls.

EXPLAIN

For slow SQL:

EXPLAIN SELECT ...

Inspect:

  • type
  • possible_keys
  • key
  • rows
  • Extra

---

# 11. `.cursor/skills/yii2-backend/references/review.md`

```md
# Yii2 Code Review Checklist

## PHP

- [ ] PHP version compatible
- [ ] types appropriate
- [ ] null handling
- [ ] exception handling
- [ ] no unnecessary duplication

## Yii2

- [ ] Controller is thin
- [ ] validation exists
- [ ] ActiveRecord relations checked
- [ ] N+1 checked
- [ ] transaction scope correct
- [ ] behaviors/events considered

## MySQL

- [ ] indexes checked
- [ ] unnecessary SQL avoided
- [ ] large result set controlled
- [ ] batch processing considered
- [ ] transaction performance checked

## Redis

- [ ] key naming consistent
- [ ] TTL exists where appropriate
- [ ] cache invalidation considered
- [ ] distributed lock has timeout
- [ ] queue job is idempotent

## Security

- [ ] authentication
- [ ] authorization
- [ ] SQL injection
- [ ] XSS
- [ ] CSRF
- [ ] IDOR
- [ ] mass assignment
- [ ] file upload
- [ ] SSRF
- [ ] command injection
- [ ] secrets

## API

- [ ] input validation
- [ ] response compatibility
- [ ] status codes
- [ ] pagination
- [ ] sensitive fields excluded

## Testing

- [ ] regression test
- [ ] edge cases
- [ ] relevant tests executed
- [ ] no false test claims

推荐使用方式

完成配置后,可以直接在 Cursor Agent 中这样使用:

帮我分析这个 Yii2 项目的订单创建流程。

先不要改代码。

先找出:
1. Controller
2. Model
3. Service
4. 数据库表
5. Redis
6. 事务
7. 权限验证
8. 可能的 N+1

最后给出改造方案。

然后:

按照刚才的方案实施。

要求:
1. 不修改无关文件
2. 保持现有 API 兼容
3. 保持 Yii2 项目现有架构
4. 所有数据库写操作检查事务
5. 检查 N+1
6. 增加必要测试
7. 修改完成后运行相关测试

代码完成后:

请按照 yii2-backend 的 review checklist 对刚才的修改进行 Code Review。

重点检查:
- N+1
- SQL 性能
- Redis
- 事务
- 并发
- 权限
- IDOR
- 参数验证
- API 兼容性
- PHP 内存
- 大数据量处理

不要修改代码,只输出问题和严重程度。

最后:

根据刚才 Code Review 的结果修复所有 P0/P1 问题。

修复后重新运行相关测试,并告诉我实际执行了哪些测试。
最后修改于:2026年08月31日 17:24

评论已关闭

推荐阅读

AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日
python之plot()和subplot()画图
2024年11月26日
理解 DALL·E 2、Stable Diffusion 和 Midjourney 工作原理
2024年12月01日