Laravel Interview Questions
25 questions with detailed answers
Question:
Explain Laravel's MVC architecture and how it works.
Answer:
Laravel follows the MVC (Model-View-Controller) pattern:
**Model**: Represents data and business logic. Uses Eloquent ORM.
class User extends Model {
protected $fillable = ["name", "email"];
public function posts() {
return $this->hasMany(Post::class);
}
}
**View**: Presentation layer using Blade templates.
@foreach($users as $user)
{{ $user->name }}
{{ $user->email }}
@endforeach
**Controller**: Handles HTTP requests and coordinates between Model and View.
class UserController extends Controller {
public function index() {
$users = User::all();
return view("users.index", compact("users"));
}
}Question:
How do you implement middleware in Laravel? Provide an example.
Answer:
Middleware provides a convenient mechanism for filtering HTTP requests:
**Creating Middleware:**
php artisan make:middleware CheckAge
**Middleware Implementation:**
class CheckAge {
public function handle($request, Closure $next) {
if ($request->age <= 18) {
return redirect("home");
}
return $next($request);
}
}
**Registering Middleware:**
// app/Http/Kernel.php
protected $routeMiddleware = [
"age" => AppHttpMiddlewareCheckAge::class,
];
**Using Middleware:**
Route::get("admin", function () {
//
})->middleware("age");Question:
Explain Eloquent relationships with code examples.
Answer:
Eloquent provides several relationship types:
**One-to-One:**
class User extends Model {
public function profile() {
return $this->hasOne(Profile::class);
}
}
class Profile extends Model {
public function user() {
return $this->belongsTo(User::class);
}
}
**One-to-Many:**
class Post extends Model {
public function comments() {
return $this->hasMany(Comment::class);
}
}
class Comment extends Model {
public function post() {
return $this->belongsTo(Post::class);
}
}
**Many-to-Many:**
class User extends Model {
public function roles() {
return $this->belongsToMany(Role::class);
}
}Question:
How do you handle form validation in Laravel?
Answer:
Laravel provides multiple ways to validate forms:\n\n**Controller Validation:**\n```php\npublic function store(Request $request) {\n $validated = $request->validate([\n 'name' => 'required|max:255',\n 'email' => 'required|email|unique:users',\n 'password' => 'required|min:8|confirmed'\n ]);\n \n User::create($validated);\n}\n```\n\n**Form Request Validation:**\n```php\nphp artisan make:request StoreUserRequest\n\nclass StoreUserRequest extends FormRequest {\n public function rules() {\n return [\n 'name' => 'required|max:255',\n 'email' => 'required|email|unique:users'\n ];\n }\n \n public function messages() {\n return [\n 'name.required' => 'Name is required',\n 'email.unique' => 'Email already exists'\n ];\n }\n}\n```
Question:
How do you implement caching in Laravel? Explain different cache drivers.
Answer:
Laravel provides multiple cache drivers:\n\n**Configuration:**\n```php\n// config/cache.php\n'default' => env('CACHE_DRIVER', 'file'),\n'stores' => [\n 'redis' => [\n 'driver' => 'redis',\n 'connection' => 'cache',\n ],\n 'database' => [\n 'driver' => 'database',\n 'table' => 'cache',\n ]\n]\n```\n\n**Usage Examples:**\n```php\n// Store cache\nCache::put('key', 'value', 3600);\n\n// Retrieve cache\n$value = Cache::get('key', 'default');\n\n// Cache with closure\n$users = Cache::remember('users', 3600, function () {\n return User::all();\n});\n\n// Tags (Redis/Memcached only)\nCache::tags(['people', 'authors'])->put('John', $john, 3600);\nCache::tags(['people'])->flush();\n```
Question:
Explain Laravel Livewire integration in Laravel with code examples.
Answer:
Laravel Livewire enables building dynamic interfaces without JavaScript:
**Installation:**
composer require livewire/livewire
php artisan livewire:publish --config
**Creating Component:**
php artisan make:livewire Counter
**Component Class (app/Http/Livewire/Counter.php):**
class Counter extends Component {
public $count = 0;
public function increment() {
$this->count++;
}
public function decrement() {
$this->count--;
}
public function render() {
return view("livewire.counter");
}
}
**Component View (resources/views/livewire/counter.blade.php):**
{{ $count }}
**Using in Blade:**
@livewire("counter")
Question:
Explain Custom Blade components in Laravel with code examples.
Answer:
Custom Blade components provide reusable UI elements:
**Creating Component:**
php artisan make:component Alert
**Component Class (app/View/Components/Alert.php):**
class Alert extends Component {
public $type;
public $message;
public function __construct($type = "info", $message = "") {
$this->type = $type;
$this->message = $message;
}
public function render() {
return view("components.alert");
}
}
**Component Template (resources/views/components/alert.blade.php):**
{{ ucfirst($type) }}!
{{ $message ?? $slot }}
**Using Component:**
Something went wrong!
Question:
Explain API resource transformations in Laravel with code examples.
Answer:
API Resources provide a transformation layer between models and JSON responses:
**Creating Resource:**
php artisan make:resource UserResource
php artisan make:resource UserCollection
**Resource Class (app/Http/Resources/UserResource.php):**
class UserResource extends JsonResource {
public function toArray($request) {
return [
"id" => $this->id,
"name" => $this->name,
"email" => $this->email,
"created_at" => $this->created_at->format("Y-m-d H:i:s"),
"posts_count" => $this->posts->count(),
"posts" => PostResource::collection($this->whenLoaded("posts")),
"profile" => new ProfileResource($this->whenLoaded("profile")),
];
}
public function with($request) {
return [
"version" => "1.0",
"author_url" => url("http://author.com"),
];
}
}
**Using in Controller:**
public function show(User $user) {
return new UserResource($user->load("posts", "profile"));
}
public function index() {
return UserResource::collection(User::paginate());
}Question:
Explain Database indexing strategies in Laravel with code examples.
Answer:
Database indexing improves query performance:
**Creating Indexes in Migrations:**
Schema::table("users", function (Blueprint $table) {
// Single column index
$table->index("email");
// Composite index
$table->index(["status", "created_at"]);
// Unique index
$table->unique("username");
// Full-text index
$table->fullText(["title", "content"]);
});
**Index Types:**
// Primary key (automatic)
$table->id();
// Foreign key with index
$table->foreignId("user_id")->constrained();
// Custom index names
$table->index("email", "users_email_index");
**Query Optimization:**
// Use indexed columns in WHERE clauses
User::where("email", "john@example.com")->first();
// Composite index usage
User::where("status", "active")
->where("created_at", ">", now()->subDays(30))
->get();
**Dropping Indexes:**
$table->dropIndex("users_email_index");
$table->dropUnique("users_username_unique");Question:
Explain Laravel Horizon configuration in Laravel with code examples.
Answer:
Laravel Horizon provides a dashboard and configuration system for Redis queues:
**Installation:**
composer require laravel/horizon
php artisan horizon:install
php artisan migrate
**Configuration (config/horizon.php):**
return [
"use" => "default",
"prefix" => env("HORIZON_PREFIX", "horizon:"),
"middleware" => ["web"],
"waits" => [
"redis:default" => 60,
],
"trim" => [
"recent" => 60,
"pending" => 60,
"completed" => 60,
"failed" => 10080,
],
"environments" => [
"production" => [
"supervisor-1" => [
"connection" => "redis",
"queue" => ["default"],
"balance" => "simple",
"processes" => 10,
"tries" => 3,
],
],
"local" => [
"supervisor-1" => [
"connection" => "redis",
"queue" => ["default"],
"balance" => "simple",
"processes" => 3,
"tries" => 3,
],
],
],
];
**Starting Horizon:**
php artisan horizon
**Job Monitoring:**
// Access dashboard at /horizon
// Monitor failed jobs, throughput, and wait timesQuestion:
Explain Custom validation rules in Laravel with code examples.
Answer:
Custom validation rules allow creating reusable validation logic:
**Creating Rule:**
php artisan make:rule Uppercase
**Rule Implementation (app/Rules/Uppercase.php):**
class Uppercase implements Rule {
public function passes($attribute, $value) {
return strtoupper($value) === $value;
}
public function message() {
return "The :attribute must be uppercase.";
}
}
**Using Custom Rule:**
use AppRulesUppercase;
public function store(Request $request) {
$request->validate([
"name" => ["required", new Uppercase],
"email" => "required|email",
]);
}
**Closure-based Rule:**
$request->validate([
"name" => [
"required",
function ($attribute, $value, $fail) {
if (strtoupper($value) !== $value) {
$fail("The $attribute must be uppercase.");
}
},
],
]);Question:
Explain File upload handling in Laravel with code examples.
Answer:
Laravel provides robust file upload handling:
**Basic File Upload:**
public function store(Request $request) {
$request->validate([
"avatar" => "required|image|mimes:jpeg,png,jpg|max:2048"
]);
$path = $request->file("avatar")->store("avatars", "public");
auth()->user()->update(["avatar" => $path]);
}
**Custom File Handling:**
public function uploadDocument(Request $request) {
if ($request->hasFile("document")) {
$file = $request->file("document");
$filename = time() . "." . $file->getClientOriginalExtension();
$file->storeAs("documents", $filename, "public");
Document::create([
"name" => $file->getClientOriginalName(),
"path" => "documents/" . $filename,
"size" => $file->getSize(),
]);
}
}
**Multiple File Upload:**
public function uploadMultiple(Request $request) {
$request->validate([
"files.*" => "required|file|max:10240"
]);
foreach ($request->file("files") as $file) {
$file->store("uploads", "public");
}
}Question:
Explain Multi-tenancy implementation in Laravel with code examples.
Answer:
Multi-tenancy allows serving multiple tenants from single application:
**Single Database Approach:**
// Migration
Schema::create("tenants", function (Blueprint $table) {
$table->id();
$table->string("name");
$table->string("domain");
$table->timestamps();
});
// Add tenant_id to all tables
$table->foreignId("tenant_id")->constrained();
**Tenant Model:**
class Tenant extends Model {
protected $fillable = ["name", "domain"];
public function users() {
return $this->hasMany(User::class);
}
}
**Middleware for Tenant Resolution:**
class ResolveTenant {
public function handle($request, Closure $next) {
$domain = $request->getHost();
$tenant = Tenant::where("domain", $domain)->first();
if (!$tenant) {
abort(404);
}
app()->instance("tenant", $tenant);
return $next($request);
}
}
**Global Scope for Models:**
class TenantScope implements Scope {
public function apply(Builder $builder, Model $model) {
if (app()->has("tenant")) {
$builder->where("tenant_id", app("tenant")->id);
}
}
}Question:
Explain Laravel's Service Container and Dependency Injection.
Answer:
The Service Container is Laravel's dependency injection container:\n\n**Binding Services:**\n```php\n// AppServiceProvider\npublic function register() {\n $this->app->bind('PaymentGateway', function ($app) {\n return new StripePaymentGateway(\n config('services.stripe.key')\n );\n });\n}\n```\n\n**Dependency Injection:**\n```php\nclass OrderController extends Controller {\n protected $paymentGateway;\n \n public function __construct(PaymentGateway $paymentGateway) {\n $this->paymentGateway = $paymentGateway;\n }\n \n public function process(Request $request) {\n return $this->paymentGateway->charge(\n $request->amount\n );\n }\n}\n```\n\n**Method Injection:**\n```php\npublic function show(User $user, PaymentGateway $gateway) {\n // Laravel automatically resolves dependencies\n}\n```
Question:
Explain Laravel Queues and how to implement background job processing.
Answer:
Laravel Queues allow deferring time-consuming tasks:\n\n**Job Creation:**\n```bash\nphp artisan make:job ProcessPayment\n```\n\n**Job Implementation:**\n```php\nclass ProcessPayment implements ShouldQueue {\n use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;\n \n protected $order;\n \n public function __construct(Order $order) {\n $this->order = $order;\n }\n \n public function handle() {\n // Process payment logic\n PaymentGateway::charge($this->order);\n }\n \n public function failed(Exception $exception) {\n // Handle job failure\n }\n}\n```\n\n**Dispatching Jobs:**\n```php\n// Dispatch immediately\nProcessPayment::dispatch($order);\n\n// Dispatch with delay\nProcessPayment::dispatch($order)->delay(now()->addMinutes(10));\n\n// Dispatch to specific queue\nProcessPayment::dispatch($order)->onQueue('payments');\n```
Question:
How do you implement API authentication using Laravel Sanctum?
Answer:
Laravel Sanctum provides API token authentication:\n\n**Installation:**\n```bash\ncomposer require laravel/sanctum\nphp artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"\nphp artisan migrate\n```\n\n**Model Setup:**\n```php\nuse Laravel\Sanctum\HasApiTokens;\n\nclass User extends Authenticatable {\n use HasApiTokens, HasFactory, Notifiable;\n}\n```\n\n**Token Creation:**\n```php\n// Login endpoint\npublic function login(Request $request) {\n $credentials = $request->validate([\n 'email' => 'required|email',\n 'password' => 'required'\n ]);\n \n if (Auth::attempt($credentials)) {\n $user = Auth::user();\n $token = $user->createToken('API Token')->plainTextToken;\n \n return response()->json([\n 'token' => $token,\n 'user' => $user\n ]);\n }\n \n return response()->json(['error' => 'Unauthorized'], 401);\n}\n```\n\n**Protected Routes:**\n```php\nRoute::middleware('auth:sanctum')->group(function () {\n Route::get('/user', function (Request $request) {\n return $request->user();\n });\n});\n```
Question:
Explain Laravel Events and Listeners with practical examples.
Answer:
Events provide a simple observer pattern implementation:\n\n**Event Creation:**\n```bash\nphp artisan make:event UserRegistered\nphp artisan make:listener SendWelcomeEmail --event=UserRegistered\n```\n\n**Event Class:**\n```php\nclass UserRegistered {\n use Dispatchable, InteractsWithSockets, SerializesModels;\n \n public $user;\n \n public function __construct(User $user) {\n $this->user = $user;\n }\n}\n```\n\n**Listener Class:**\n```php\nclass SendWelcomeEmail {\n public function handle(UserRegistered $event) {\n Mail::to($event->user->email)\n ->send(new WelcomeMail($event->user));\n }\n}\n```\n\n**Event Registration:**\n```php\n// EventServiceProvider\nprotected $listen = [\n UserRegistered::class => [\n SendWelcomeEmail::class,\n UpdateUserStats::class,\n ],\n];\n```\n\n**Firing Events:**\n```php\n// In controller\nevent(new UserRegistered($user));\n// or\nUserRegistered::dispatch($user);\n```
Question:
How do you implement database transactions in Laravel?
Answer:
Laravel provides several ways to handle database transactions:\n\n**Automatic Transactions:**\n```php\nDB::transaction(function () {\n DB::table('users')->update(['votes' => 1]);\n DB::table('posts')->delete();\n});\n```\n\n**Manual Transactions:**\n```php\nDB::beginTransaction();\n\ntry {\n DB::table('users')->update(['votes' => 1]);\n DB::table('posts')->delete();\n \n DB::commit();\n} catch (\Exception $e) {\n DB::rollBack();\n throw $e;\n}\n```\n\n**Nested Transactions:**\n```php\nDB::transaction(function () {\n DB::table('users')->update(['votes' => 1]);\n \n DB::transaction(function () {\n DB::table('posts')->delete();\n });\n});\n```\n\n**With Retry Logic:**\n```php\nDB::transaction(function () {\n // Database operations\n}, 5); // Retry 5 times on deadlock\n```
Question:
Explain Performance optimization in Laravel with code examples.
Answer:
Laravel performance optimization involves multiple strategies:
**Database Optimization:**
// Eager Loading
$users = User::with(["posts", "profile"])->get();
// Query Optimization
$users = User::select(["id", "name", "email"])
->where("active", true)
->limit(100)
->get();
// Database Indexing
Schema::table("users", function (Blueprint $table) {
$table->index(["email", "active"]);
});
**Caching Strategies:**
// Query Caching
$users = Cache::remember("active_users", 3600, function () {
return User::where("active", true)->get();
});
// Route Caching
php artisan route:cache
// Config Caching
php artisan config:cache
**Queue Optimization:**
// Background Processing
ProcessPayment::dispatch($order)->onQueue("payments");
// Batch Jobs
Bus::batch([
new ProcessPayment($order1),
new ProcessPayment($order2),
])->dispatch();Question:
Explain Security best practices in Laravel with code examples.
Answer:
Laravel security best practices:
**Input Validation:**
public function store(Request $request) {
$validated = $request->validate([
"email" => "required|email|max:255",
"password" => "required|min:8|confirmed",
"name" => "required|string|max:255|regex:/^[a-zA-Zs]+$/"
]);
}
**CSRF Protection:**
@csrf
// Verify in middleware (automatic)
// Custom verification
if (!$request->session()->token() === $request->input("_token")) {
abort(403);
}
**SQL Injection Prevention:**
// Use Eloquent ORM (safe)
User::where("email", $email)->first();
// Use parameter binding
DB::select("SELECT * FROM users WHERE email = ?", [$email]);
// Never do this
DB::select("SELECT * FROM users WHERE email = " . $email);
**XSS Prevention:**
{{ $userInput }}
{!! $trustedContent !!}
// Manual escaping
echo htmlspecialchars($userInput, ENT_QUOTES, "UTF-8");
**Authentication & Authorization:**
// Rate limiting
Route::middleware("throttle:60,1")->group(function () {
Route::post("/login", [AuthController::class, "login"]);
});
// Authorization
$this->authorize("update", $post);Question:
Explain Testing strategies in Laravel with code examples.
Answer:
Laravel provides comprehensive testing capabilities:
**Feature Testing:**
class UserTest extends TestCase {
public function test_user_can_register() {
$response = $this->post("/register", [
"name" => "John Doe",
"email" => "john@example.com",
"password" => "password",
"password_confirmation" => "password"
]);
$response->assertRedirect("/dashboard");
$this->assertDatabaseHas("users", [
"email" => "john@example.com"
]);
}
}
**Unit Testing:**
class UserServiceTest extends TestCase {
public function test_user_creation() {
$userService = new UserService();
$user = $userService->createUser([
"name" => "Jane Doe",
"email" => "jane@example.com"
]);
$this->assertInstanceOf(User::class, $user);
$this->assertEquals("Jane Doe", $user->name);
}
}
**Database Testing:**
use RefreshDatabase;
public function test_user_has_posts() {
$user = User::factory()->create();
$posts = Post::factory(3)->create(["user_id" => $user->id]);
$this->assertCount(3, $user->posts);
}Question:
Explain Package development in Laravel with code examples.
Answer:
Laravel package development allows creating reusable components:
**Package Structure:**
my-package/
├── src/
│ ├── MyPackageServiceProvider.php
│ ├── Facades/
│ └── Commands/
├── config/
├── resources/
├── tests/
└── composer.json
**Service Provider:**
class MyPackageServiceProvider extends ServiceProvider {
public function register() {
$this->app->singleton("mypackage", function () {
return new MyPackage();
});
}
public function boot() {
$this->publishes([
__DIR__."/../config/mypackage.php" => config_path("mypackage.php"),
], "config");
$this->loadRoutesFrom(__DIR__."/../routes/web.php");
$this->loadViewsFrom(__DIR__."/../resources/views", "mypackage");
$this->loadMigrationsFrom(__DIR__."/../database/migrations");
}
}
**Facade:**
class MyPackageFacade extends Facade {
protected static function getFacadeAccessor() {
return "mypackage";
}
}
**Composer.json:**
{
"name": "vendor/my-package",
"autoload": {
"psr-4": {
"Vendor\MyPackage\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"Vendor\MyPackage\MyPackageServiceProvider"
],
"aliases": {
"MyPackage": "Vendor\MyPackage\Facades\MyPackageFacade"
}
}
}
}Question:
Explain Deployment strategies in Laravel with code examples.
Answer:
Laravel deployment strategies for production:
**Zero-Downtime Deployment:**
# Deploy script
php artisan down --message="Upgrading system" --retry=60
git pull origin main
composer install --no-dev --optimize-autoloader
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan migrate --force
php artisan queue:restart
php artisan up
**Environment Configuration:**
# .env.production
APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=production_db
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
**Docker Deployment:**
# Dockerfile
FROM php:8.1-fpm
COPY . /var/www/html
WORKDIR /var/www/html
RUN composer install --no-dev --optimize-autoloader
RUN php artisan config:cache
RUN php artisan route:cache
RUN php artisan view:cache
EXPOSE 9000
**Laravel Forge Deployment:**
# Deployment script in Forge
cd /home/forge/yourdomain.com
git pull origin main
composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan queue:restartQuestion:
Explain Error handling in Laravel with code examples.
Answer:
Laravel provides comprehensive error handling:
**Exception Handler (app/Exceptions/Handler.php):**
class Handler extends ExceptionHandler {
public function register() {
$this->reportable(function (Throwable $e) {
if ($e instanceof CustomException) {
Log::error("Custom error: " . $e->getMessage());
}
});
}
public function render($request, Throwable $e) {
if ($e instanceof ModelNotFoundException) {
return response()->json(["error" => "Resource not found"], 404);
}
return parent::render($request, $e);
}
}
**Custom Exceptions:**
class CustomException extends Exception {
public function report() {
Log::error("Custom exception occurred");
}
public function render($request) {
return response()->view("errors.custom", [], 500);
}
}
**Try-Catch Blocks:**
public function processPayment($amount) {
try {
$payment = PaymentGateway::charge($amount);
return $payment;
} catch (PaymentException $e) {
Log::error("Payment failed: " . $e->getMessage());
throw new CustomException("Payment processing failed");
} catch (Exception $e) {
Log::error("Unexpected error: " . $e->getMessage());
throw $e;
}
}
**Error Views:**
Page Not Found
The requested page could not be found.
Question:
Explain Logging configuration in Laravel with code examples.
Answer:
Laravel logging configuration and usage:
**Configuration (config/logging.php):**
return [
"default" => env("LOG_CHANNEL", "stack"),
"channels" => [
"stack" => [
"driver" => "stack",
"channels" => ["single", "slack"],
],
"single" => [
"driver" => "single",
"path" => storage_path("logs/laravel.log"),
"level" => "debug",
],
"daily" => [
"driver" => "daily",
"path" => storage_path("logs/laravel.log"),
"level" => "debug",
"days" => 14,
],
"slack" => [
"driver" => "slack",
"url" => env("LOG_SLACK_WEBHOOK_URL"),
"username" => "Laravel Log",
"level" => "error",
],
],
];
**Basic Logging:**
use IlluminateSupportFacadesLog;
// Different log levels
Log::emergency("System is down");
Log::alert("Action must be taken immediately");
Log::critical("Critical conditions");
Log::error("Error conditions");
Log::warning("Warning conditions");
Log::notice("Normal but significant condition");
Log::info("Informational messages");
Log::debug("Debug-level messages");
**Contextual Logging:**
Log::info("User login", [
"user_id" => $user->id,
"ip_address" => request()->ip(),
"user_agent" => request()->userAgent(),
]);
// Custom channel
Log::channel("slack')->error("Payment failed", [
"order_id" => $order->id,
"amount" => $order->total,
]);