ワンクリックで
laravel-conventions
Laravel best practices for Eloquent, controllers, validation, services, and testing
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Laravel best practices for Eloquent, controllers, validation, services, and testing
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
RESTful API design patterns, HTTP standards, versioning, error handling, and documentation
Joomla 4/5 component development with MVC, services, plugins, and language handling
Joomla 3.x legacy patterns with JFactory, non-namespaced MVC, JDatabase, and plugin structure
Performance optimization for PHP, JavaScript, databases, and caching strategies
PHP coding standards including strict typing, OOP patterns, error handling, and documentation
Deep dive into SOLID principles with PHP/TypeScript examples, refactoring patterns, and violation detection
| name | laravel-conventions |
| description | Laravel best practices for Eloquent, controllers, validation, services, and testing |
| license | MIT |
| compatibility | opencode |
| metadata | {"framework":"laravel","version":"10+"} |
{{ }} for auto-escapingFollow standard Laravel conventions:
app/Http/Controllers/ - Thin controllersapp/Services/ - Business logicapp/Repositories/ - Data access (optional)app/Actions/ - Single-purpose classesapp/Models/ - Eloquent models// Model definition
class User extends Model
{
protected $fillable = ['name', 'email'];
protected $casts = [
'email_verified_at' => 'datetime',
'is_active' => 'boolean',
];
// Relationships
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
// Scopes
public function scopeActive(Builder $query): Builder
{
return $query->where('is_active', true);
}
}
// Eager loading - AVOID N+1
$users = User::with(['posts', 'profile'])->get();
// Select only needed columns
$users = User::select(['id', 'name', 'email'])->get();
Keep controllers thin - delegate to services:
class UserController extends Controller
{
public function store(StoreUserRequest $request, UserService $service): JsonResponse
{
$user = $service->create($request->validated());
return response()->json(new UserResource($user), 201);
}
}
class StoreUserRequest extends FormRequest
{
public function authorize(): bool
{
return true; // Or policy check
}
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'email', 'unique:users'],
'password' => ['required', 'min:8', 'confirmed'],
];
}
}
class UserResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at->toISOString(),
'posts' => PostResource::collection($this->whenLoaded('posts')),
];
}
}
final class UserService
{
public function __construct(
private readonly UserRepositoryInterface $users
) {}
public function create(array $data): User
{
return DB::transaction(function () use ($data) {
$user = $this->users->create($data);
event(new UserCreated($user));
return $user;
});
}
}
// Feature test
public function test_user_can_be_created(): void
{
$response = $this->postJson('/api/users', [
'name' => 'John Doe',
'email' => 'john@example.com',
'password' => 'password123',
'password_confirmation' => 'password123',
]);
$response->assertStatus(201)
->assertJsonStructure(['data' => ['id', 'name', 'email']]);
$this->assertDatabaseHas('users', ['email' => 'john@example.com']);
}
->select() to limit columns->with() for eager loading->chunk() for large datasets