一键导入
laravel-conventions
Modern Laravel 11+ / PHP 8.3+ coding standards reference. Use when writing or reviewing PHP/Laravel code to ensure convention compliance.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Modern Laravel 11+ / PHP 8.3+ coding standards reference. Use when writing or reviewing PHP/Laravel code to ensure convention compliance.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Guide for structuring, parsing, and validating XML-like tags in LLM inputs, system prompts, outputs, and agent-to-agent communication. Use this skill when designing prompt templates, parsing structured content from text, or handling nested tag boundaries.
Implementation reference library for compound engineering workflows. For workflow orchestration, use slash commands under `commands/workflows/` (constitution, plan, work, review, compound). This skill provides stack-specific fix recipes those workflows consume.
Browser automation using Vercel's agent-browser CLI. Use when you need to interact with web pages, fill forms, take screenshots, or scrape data. Alternative to Playwright MCP - uses Bash commands with ref-based element selection. Triggers on "browse website", "fill form", "click button", "take screenshot", "scrape page", "web automation".
Build applications where agents are first-class citizens. Use this skill when designing autonomous agents, creating MCP tools, implementing self-modifying systems, or defining architecture artifacts around deletion tests, interfaces, seams, adapters, and explicit contracts.
Run a comprehensive scored audit of agent-native architecture principles
This skill should be used before implementing features, building components, or making changes. It guides exploring user intent, approaches, and design decisions before planning. Triggers on "let's brainstorm", "help me think through", "what should we build", "explore approaches", ambiguous feature requests, or when the user's request has multiple valid interpretations that need clarification.
| name | laravel-conventions |
| description | Modern Laravel 11+ / PHP 8.3+ coding standards reference. Use when writing or reviewing PHP/Laravel code to ensure convention compliance. |
| model | claude-sonnet-4.6 |
| platforms | {"copilot":{"model":"gpt-5.3-codex"},"opencode":{"model":"openrouter/moonshotai/kimi-k2.6"}} |
Reference skill for modern Laravel coding standards and PHP 8.3+ best practices.
Controller -> FormRequest -> Action/Service -> Model
CreateUser, ProcessPayment)declare(strict_types=1);
// Readonly classes for DTOs
readonly class CreateUserData {
public function __construct(
public string $name,
public string $email,
public ?string $phone = null,
) {}
}
// Enums instead of constants
enum UserStatus: string {
case Active = 'active';
case Suspended = 'suspended';
case Pending = 'pending';
}
// First-class callable syntax
$users->map($this->transformUser(...));
// Named arguments for clarity
Cache::put(key: $cacheKey, value: $data, ttl: 3600);
// Match expressions over switch
$label = match($status) {
UserStatus::Active => 'Active User',
UserStatus::Suspended => 'Account Suspended',
default => 'Unknown',
};
| Type | Convention | Example |
|---|---|---|
| Classes | PascalCase | UserService |
| Methods | camelCase | getUserById |
| Properties/Variables | camelCase | $userData |
| Constants | UPPER_SNAKE_CASE | MAX_RETRIES |
| Database tables | plural, snake_case | user_accounts |
| Database columns | snake_case | created_at |
| Routes | kebab-case | /user-profiles |
| Config keys | snake_case | cache.default_ttl |
| Enums | PascalCase | UserStatus::Active |
declare(strict_types=1) at the top of every PHP file[] with trailing commasmixed type unless absolutely necessaryapp/
├── Actions/ # Single-purpose action classes
├── Console/Commands/ # Artisan commands
├── DTOs/ # Readonly data transfer objects
├── Enums/ # PHP 8.1+ backed enums
├── Events/ # Event classes
├── Exceptions/ # Custom exceptions
├── Http/
│ ├── Controllers/ # API/Web controllers
│ ├── Middleware/ # Request middleware
│ ├── Requests/ # FormRequest validation
│ └── Resources/ # API Resources (JSON transformations)
├── Jobs/ # Queued jobs
├── Listeners/ # Event listeners
├── Mail/ # Mailable classes
├── Models/ # Eloquent models
│ └── Concerns/ # Model traits
├── Notifications/ # Notification classes
├── Observers/ # Model observers
├── Policies/ # Authorization policies
├── Providers/ # Service providers
├── Rules/ # Custom validation rules
└── Services/ # Business logic services
database/
├── factories/ # Model factories
├── migrations/ # Database migrations
└── seeders/ # Database seeders
routes/
├── api.php # API routes
├── web.php # Web routes
└── console.php # Console routes (Laravel 11+)
tests/
├── Feature/ # Feature/integration tests
├── Unit/ # Unit tests
└── Pest.php # Pest configuration
// Use $casts property (not method unless dynamic)
protected $casts = [
'email_verified_at' => 'datetime',
'status' => UserStatus::class,
'settings' => 'array',
'is_admin' => 'boolean',
];
// Scope queries for reuse
public function scopeActive(Builder $query): Builder
{
return $query->where('status', UserStatus::Active);
}
// Prevent lazy loading in development
// In AppServiceProvider::boot()
Model::preventLazyLoading(! app()->isProduction());
// Use strict mode
Model::shouldBeStrict(! app()->isProduction());
// Eager load relationships
User::with(['posts', 'profile'])->get();
// Use whenLoaded in API Resources
'posts' => PostResource::collection($this->whenLoaded('posts')),
YYYY_MM_DD_HHMMSS_description.php
down() method for rollbacksforeignId() and constrained() for foreign keysafter() to control column orderSchema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('title');
$table->string('slug')->unique();
$table->text('body');
$table->enum('status', ['draft', 'published', 'archived'])->default('draft');
$table->timestamp('published_at')->nullable();
$table->timestamps();
$table->softDeletes();
$table->index(['status', 'published_at']);
});
// Always use API Resources for JSON responses
class UserResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'posts' => PostResource::collection($this->whenLoaded('posts')),
'created_at' => $this->created_at->toISOString(),
];
}
}
// In controller
return UserResource::make($user);
return UserResource::collection($users);
// Implement ShouldQueue for async processing
class ProcessPayment implements ShouldQueue
{
use Queueable;
public int $tries = 3;
public int $backoff = 60;
public int $timeout = 120;
public function __construct(
private readonly Order $order,
) {}
public function handle(PaymentGateway $gateway): void
{
$gateway->charge($this->order);
}
public function failed(\Throwable $exception): void
{
// Notify team of failure
}
}
// Use typed events
class OrderPlaced
{
public function __construct(
public readonly Order $order,
) {}
}
// Auto-discovered listeners (Laravel 11+)
// Just type-hint the event in handle()
class SendOrderConfirmation
{
public function handle(OrderPlaced $event): void
{
$event->order->user->notify(new OrderConfirmationNotification($event->order));
}
}
// Use controller class references
Route::apiResource('users', UserController::class);
// Group related routes
Route::prefix('admin')->middleware('auth:sanctum', 'admin')->group(function () {
Route::apiResource('users', Admin\UserController::class);
});
// Single-action controllers
Route::post('/webhooks/stripe', StripeWebhookController::class);
$request->validated() to only access validated dataencrypt()/decrypt() for sensitive data at rest// Custom exceptions with render method
class InsufficientFundsException extends Exception
{
public function render(Request $request): JsonResponse
{
return response()->json([
'message' => 'Insufficient funds for this transaction.',
], 422);
}
}
// Use abort helpers
abort_if(! $user->canAccess($resource), 403);
abort_unless($order->isPending(), 422, 'Order is no longer pending.');
// Feature test
it('creates a user', function () {
$response = postJson('/api/users', [
'name' => 'Jane Doe',
'email' => 'jane@example.com',
'password' => 'secure-password',
]);
$response->assertCreated()
->assertJsonPath('data.name', 'Jane Doe');
$this->assertDatabaseHas('users', ['email' => 'jane@example.com']);
});
// Unit test with mocking
it('calculates order total with tax', function () {
$order = Order::factory()->create(['subtotal' => 10000]);
expect($order->totalWithTax())->toBe(10800);
});
// Use datasets for parameterized tests
it('validates required fields', function (string $field) {
$data = User::factory()->make()->toArray();
unset($data[$field]);
postJson('/api/users', $data)->assertUnprocessable()
->assertJsonValidationErrors($field);
})->with(['name', 'email', 'password']);
# All tests
php artisan test
# With Pest directly
./vendor/bin/pest
# Specific test file
./vendor/bin/pest tests/Feature/UserTest.php
# Filter by name
./vendor/bin/pest --filter "creates a user"
# Parallel execution
php artisan test --parallel
./vendor/bin/pint
# Check only (no changes)
./vendor/bin/pint --test
# Static analysis
./vendor/bin/phpstan analyse