PHP Laravel Developer Interview Questions 2026: Complete Preparation Guide

Master Laravel interview questions for 2026. From Eloquent ORM and Service Container to queues, testing, and Laravel 13 features, prepare for technical interviews with real-world examples.

PHP Laravel developer interview preparation with code examples

PHP Laravel developer interview questions test both framework knowledge and software design principles. With Laravel 13 released in March 2026 introducing the AI SDK, PHP Attributes, and Passkey authentication, interviewers expect candidates to demonstrate awareness of current features alongside core fundamentals.

Interview Focus Areas

Laravel interviews typically cover five pillars: Eloquent ORM relationships and performance, Service Container and dependency injection, authentication and authorization patterns, queue and job handling, and testing strategies. Senior roles add architecture decisions and package ecosystem knowledge.

Eloquent ORM and Database Questions

Eloquent remains the most discussed topic in Laravel interviews. Interviewers assess whether candidates understand lazy vs eager loading, relationship types, and query optimization.

Q: What is the N+1 query problem and how does Laravel solve it?

The N+1 problem occurs when code executes one query to fetch a collection, then N additional queries to load related data for each item. Laravel provides eager loading via with() to solve this.

app/Http/Controllers/PostController.phpphp
// N+1 problem: 1 query for posts + N queries for authors
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->author->name; // Triggers a query per post
}

// Solution: Eager load with with()
$posts = Post::with('author')->get(); // 2 queries total
foreach ($posts as $post) {
    echo $post->author->name; // No additional query
}

Laravel 13 maintains strict mode in development, which throws an exception when lazy loading occurs, helping catch N+1 issues early.

Q: Explain the difference between hasOne, hasMany, belongsTo, and belongsToMany.

RelationshipForeign Key LocationExample
hasOneOn related modelUser hasOne Profile (profiles.user_id)
hasManyOn related modelUser hasMany Posts (posts.user_id)
belongsToOn current modelPost belongsTo User (posts.user_id)
belongsToManyPivot tableUser belongsToMany Roles (role_user table)

Q: How do you handle soft deletes and what are the implications?

app/Models/Post.phpphp
use Illuminate\Database\Eloquent\SoftDeletes;

class Post extends Model
{
    use SoftDeletes;
    
    // Soft-deleted records are excluded by default
    // To include them:
    // Post::withTrashed()->get();
    // To get only trashed:
    // Post::onlyTrashed()->get();
}

Soft deletes add a deleted_at column. Queries automatically exclude soft-deleted records unless explicitly requested. This affects unique constraints and requires compound indexes that include deleted_at for optimal performance.

Service Container and Dependency Injection

The Service Container is Laravel's core. Understanding binding, resolution, and contextual injection separates junior from senior candidates.

Q: What is the Service Container and why does it matter?

The Service Container manages class dependencies and performs dependency injection. It resolves classes automatically, enabling loose coupling and testability.

app/Providers/AppServiceProvider.phpphp
public function register(): void
{
    // Interface binding
    $this->app->bind(
        PaymentGatewayInterface::class,
        StripePaymentGateway::class
    );
    
    // Singleton: same instance every time
    $this->app->singleton(ReportGenerator::class, function ($app) {
        return new ReportGenerator($app->make(Cache::class));
    });
}

Q: What is the difference between bind(), singleton(), and instance()?

  • bind(): Creates a new instance each time the class is resolved
  • singleton(): Creates one instance and returns the same instance on subsequent resolutions
  • instance(): Binds an existing object instance to the container
app/Providers/AppServiceProvider.phpphp
// bind: new instance each time
$this->app->bind(Service::class, fn() => new Service());

// singleton: one instance for entire request lifecycle
$this->app->singleton(Cache::class, fn() => new RedisCache());

// instance: bind an already-instantiated object
$config = new Config(['debug' => true]);
$this->app->instance(Config::class, $config);

For practice on Service Container concepts, see the Service Container & DI module.

Ready to ace your Laravel interviews?

Practice with our interactive simulators, flashcards, and technical tests.

Authentication and Authorization Patterns

Laravel 13 introduced Passkey authentication alongside existing methods. Interviewers expect knowledge of Sanctum, Passport, policies, and gates.

Q: When would you use Sanctum vs Passport?

FeatureSanctumPassport
Use caseSPA, mobile apps, simple API tokensOAuth2 server, third-party access
Token typeSimple API tokens, session-basedOAuth2 access tokens, refresh tokens
ComplexityMinimal setupFull OAuth2 implementation
Token scopesAbilities (simpler)OAuth scopes

Sanctum fits most applications. Passport is necessary when the application must act as an OAuth2 provider for third-party clients. See the detailed comparison in Laravel Sanctum vs Passport.

Q: How do policies differ from gates?

Gates are closure-based authorization checks. Policies are classes that group authorization logic for a specific model.

app/Policies/PostPolicy.phpphp
class PostPolicy
{
    public function update(User $user, Post $post): bool
    {
        return $user->id === $post->user_id;
    }
    
    public function delete(User $user, Post $post): bool
    {
        return $user->id === $post->user_id 
            || $user->hasRole('admin');
    }
}

// Usage in controller
public function update(Request $request, Post $post)
{
    $this->authorize('update', $post); // Uses PostPolicy
    // ... update logic
}

The Authorization & Policies module covers advanced authorization patterns.

Queue and Job Processing

Queues are essential for scalable Laravel applications. Interviewers probe understanding of job design, failure handling, and queue drivers.

Q: How do you handle failed jobs in Laravel?

app/Jobs/ProcessPodcast.phpphp
class ProcessPodcast implements ShouldQueue
{
    use Queueable;
    
    public int $tries = 3;
    public int $backoff = 60; // seconds between retries
    public int $timeout = 120;
    
    public function handle(): void
    {
        // Job logic
    }
    
    public function failed(Throwable $exception): void
    {
        // Notify admin, log to external service
        Log::error('Podcast processing failed', [
            'podcast_id' => $this->podcast->id,
            'error' => $exception->getMessage()
        ]);
    }
}

Failed jobs are stored in the failed_jobs table. Use php artisan queue:retry to retry specific jobs or queue:retry all for batch retry.

Q: What is the difference between dispatch() and dispatchSync()?

  • dispatch(): Pushes the job to the queue for asynchronous processing
  • dispatchSync(): Executes the job immediately in the current process, bypassing the queue

dispatchSync() is useful for testing or when the result is needed immediately. In production, most jobs should use dispatch() to avoid blocking the request.

Testing in Laravel with Pest

Laravel 13 ships with Pest as the default testing framework. Interviewers assess understanding of feature tests, unit tests, mocking, and database testing strategies.

Q: How do you test a controller that depends on an external API?

tests/Feature/PaymentTest.phpphp
use App\Services\PaymentGateway;
use App\Services\FakePaymentGateway;

test('payment is processed successfully', function () {
    // Bind fake implementation for testing
    $this->app->bind(
        PaymentGateway::class,
        FakePaymentGateway::class
    );
    
    $response = $this->postJson('/api/payments', [
        'amount' => 1000,
        'currency' => 'usd'
    ]);
    
    $response->assertStatus(200)
        ->assertJson(['status' => 'completed']);
});

test('payment handles gateway errors', function () {
    $mock = Mockery::mock(PaymentGateway::class);
    $mock->shouldReceive('charge')
        ->once()
        ->andThrow(new PaymentFailedException('Card declined'));
    
    $this->app->instance(PaymentGateway::class, $mock);
    
    $response = $this->postJson('/api/payments', [
        'amount' => 1000,
        'currency' => 'usd'
    ]);
    
    $response->assertStatus(422);
});

Q: What is RefreshDatabase vs DatabaseTransactions?

  • RefreshDatabase: Migrates the database once per test class, wraps each test in a transaction
  • DatabaseTransactions: Assumes the database is already migrated, wraps each test in a transaction

RefreshDatabase is safer for CI/CD pipelines. DatabaseTransactions is faster for local development when the schema is stable.

For testing best practices, see Laravel Testing with Pest.

Laravel 13 Specific Questions

Interviewers increasingly ask about Laravel 13 features announced at Laracon EU 2026.

Q: What is the Laravel AI SDK and when would you use it?

The Laravel AI SDK provides a unified API for AI operations: text generation, embeddings, tool-calling agents, audio, and image generation. It abstracts provider differences between OpenAI, Anthropic, and other providers.

config/ai.php defines the default providerphp
// Usage in application code
use Illuminate\Support\Facades\AI;

$response = AI::text('Summarize this article for a developer audience')
    ->withContext($articleContent)
    ->generate();

// Embeddings for semantic search
$embedding = AI::embeddings($searchQuery)->generate();
$results = Post::query()
    ->nearestNeighbors('embedding', $embedding, 10)
    ->get();

The SDK is appropriate for applications requiring AI features without managing multiple provider SDKs.

Q: How do PHP Attributes work in Laravel 13?

Laravel 13 introduced PHP 8 Attributes as an alternative to class properties for component configuration. This is non-breaking: property-based configuration continues to work.

php
// Traditional approach
class SendWelcomeEmail implements ShouldQueue
{
    public $queue = 'emails';
    public $tries = 3;
}

// Laravel 13 with Attributes
use Illuminate\Contracts\Queue\Attributes\Queue;
use Illuminate\Contracts\Queue\Attributes\Tries;

#[Queue('emails')]
#[Tries(3)]
class SendWelcomeEmail implements ShouldQueue
{
    // Cleaner class body
}

Attributes provide better IDE support and keep configuration visible at the class definition level.

Start practicing!

Test your knowledge with our interview simulators and technical tests.

Key Takeaways for Laravel Interviews in 2026

  • Master Eloquent eager loading with with() and understand strict mode that catches N+1 queries in development
  • Explain Service Container bindings: bind() for transient, singleton() for shared instances, contextual binding for interface resolution
  • Know when to use Sanctum vs Passport: Sanctum for first-party apps, Passport for OAuth2 provider scenarios
  • Demonstrate queue failure handling with $tries, $backoff, and the failed() method
  • Write tests with Pest, use mocks for external dependencies, and understand the difference between RefreshDatabase and DatabaseTransactions
  • Be familiar with Laravel 13 features: AI SDK for unified AI operations, PHP Attributes for cleaner component configuration, and Passkey authentication
  • Practice explaining trade-offs, not just implementations: interviewers value reasoning over memorization
Daily challenge

Can you spot the bug in Laravel?

One real snippet, one hidden bug, one attempt a day. No account needed to try.

Anthony Fillion-Maillet

Written by

Anthony Fillion-Maillet

Founder of SharpSkill

Full-stack developer for over 10 years. Runs SharpSkill and answers for everything published here.

Updated on September 7, 2026

Tags

#laravel
#php
#interview
#eloquent
#laravel-13

Share

Related articles