Skip to content

๐Ÿ”ง Troubleshooting Guide โ€‹

Common problems you might encounter when implementing these coding standards, with practical solutions.

๐Ÿ› Code Quality Issues โ€‹

"Class not found" Errors After Refactoring โ€‹

Problem: After moving classes to new namespaces, getting "Class not found" errors.

Target class [App\Services\UserService] does not exist.

Solutions:

bash
# 1. Clear and regenerate autoload files
composer dump-autoload

# 2. Clear application cache
php artisan cache:clear
php artisan config:clear
php artisan route:clear

# 3. If using IDE, invalidate caches
# PHPStorm: File โ†’ Invalidate Caches / Restart

Prevention:

php
// Always use proper namespace
namespace App\Services;

// Always import dependencies
use App\Repositories\Interfaces\UserRepositoryInterface;

Type Errors with Strict Types โ€‹

Problem: Getting type errors after adding declare(strict_types=1).

TypeError: UserService::createUser(): Argument #1 ($data) must be of type array, string given

Solution:

php
<?php

declare(strict_types=1);

// โŒ BEFORE: No type checking
public function createUser($data)
{
    // Accepts anything
}

// โœ… AFTER: Proper type checking
public function createUser(array $data): User
{
    // Validates at runtime
    if (!isset($data['name'], $data['email'])) {
        throw new \InvalidArgumentException('Missing required fields');
    }
    
    return $this->userRepository->create($data);
}

PHPStan/Larastan Errors โ€‹

Problem: PHPStan shows errors like "Property App\Models\User::$posts does not exist"

Solution:

php
<?php

// Use proper PHPDoc annotations
/**
 * @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Post> $posts
 */
class User extends Model
{
    public function posts(): HasMany
    {
        return $this->hasMany(Post::class);
    }
}

// Or use IDE Helper
composer require --dev barryvdh/laravel-ide-helper
php artisan ide-helper:models
php artisan ide-helper:generate
php artisan ide-helper:meta

๐Ÿ—๏ธ Architecture Issues โ€‹

Dependency Injection Not Working โ€‹

Problem: Constructor injection failing with "Target class does not exist"

Illuminate\Contracts\Container\BindingResolutionException
Target class [App\Repositories\Interfaces\UserRepositoryInterface] does not exist.

Solution:

php
<?php

// app/Providers/RepositoryServiceProvider.php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Repositories\Interfaces\UserRepositoryInterface;
use App\Repositories\UserRepository;

class RepositoryServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        // Bind interface to implementation
        $this->app->bind(
            UserRepositoryInterface::class,
            UserRepository::class
        );
    }
}

// Register in config/app.php
'providers' => [
    // ...
    App\Providers\RepositoryServiceProvider::class,
],

Circular Dependency โ€‹

Problem: Service A depends on Service B, which depends on Service A.

Illuminate\Contracts\Container\CircularDependencyException
Circular dependency detected while resolving [App\Services\UserService]

Solution:

php
<?php

// โŒ BAD: Circular dependency
class UserService
{
    public function __construct(
        private OrderService $orderService  // Depends on OrderService
    ) {}
}

class OrderService
{
    public function __construct(
        private UserService $userService  // Depends on UserService - CIRCULAR!
    ) {}
}

// โœ… GOOD: Break the circle
class UserService
{
    public function __construct(
        private UserRepositoryInterface $userRepository
    ) {}
    
    // Get order service when needed
    public function getUserOrders(int $userId): Collection
    {
        return app(OrderService::class)->getOrdersByUser($userId);
    }
}

// Or better: Use events
class UserService
{
    public function createUser(array $data): User
    {
        $user = $this->userRepository->create($data);
        
        // Dispatch event instead of direct call
        event(new UserCreated($user));
        
        return $user;
    }
}

๐Ÿ’พ Database Issues โ€‹

N+1 Query Problems โ€‹

Problem: Application slow, Telescope showing hundreds of duplicate queries.

Loaded 100 users
Query "SELECT * FROM profiles WHERE user_id = ?" executed 100 times

Solution:

php
<?php

// โŒ BEFORE: N+1 Problem
$users = User::all();
foreach ($users as $user) {
    echo $user->profile->bio;  // N queries
}

// โœ… AFTER: Eager loading
$users = User::with('profile')->get();
foreach ($users as $user) {
    echo $user->profile->bio;  // 1 query
}

// Debug with Telescope
// Visit /telescope to see query counts

Migration Errors โ€‹

Problem: Migration fails with "Table already exists"

SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'users' already exists

Solutions:

bash
# 1. Check migration status
php artisan migrate:status

# 2. Rollback last migration
php artisan migrate:rollback

# 3. Reset all migrations (CAREFUL!)
php artisan migrate:fresh

# 4. Use migrate:fresh with seeding
php artisan migrate:fresh --seed

Foreign Key Constraint Errors โ€‹

Problem: Cannot delete record due to foreign key constraint.

SQLSTATE[23000]: Integrity constraint violation: 
1451 Cannot delete or update a parent row: 
a foreign key constraint fails

Solution:

php
<?php

// Option 1: Use cascade in migration
Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')
          ->constrained()
          ->cascadeOnDelete();  // Delete posts when user deleted
});

// Option 2: Soft delete the parent
class User extends Model
{
    use SoftDeletes;  // Don't actually delete, just mark as deleted
}

// Option 3: Handle in code
public function deleteUser(int $id): bool
{
    DB::transaction(function () use ($id) {
        // Delete related records first
        Post::where('user_id', $id)->delete();
        Comment::where('user_id', $id)->delete();
        
        // Then delete user
        User::destroy($id);
    });
}

๐Ÿงช Testing Issues โ€‹

Tests Failing After Refactoring โ€‹

Problem: Tests pass locally but fail in CI/CD.

Solutions:

bash
# 1. Use consistent test database
# .env.testing
DB_CONNECTION=sqlite
DB_DATABASE=:memory:

# 2. Use RefreshDatabase
use Illuminate\Foundation\Testing\RefreshDatabase;

class UserTest extends TestCase
{
    use RefreshDatabase;
    
    // ...
}

# 3. Clear cache before tests
php artisan config:clear
php artisan cache:clear
php artisan test

Mocking Issues โ€‹

Problem: Mock not working, still calling real method.

php
<?php

// โŒ PROBLEM
$mock = $this->mock(UserService::class);
$mock->shouldReceive('createUser')->andReturn($user);
// Still calls real method!

// โœ… SOLUTION 1: Bind mock in container
$mock = Mockery::mock(UserService::class);
$mock->shouldReceive('createUser')->andReturn($user);
$this->app->instance(UserService::class, $mock);

// โœ… SOLUTION 2: Use Laravel's mock helper
$this->mock(UserService::class, function ($mock) use ($user) {
    $mock->shouldReceive('createUser')
         ->once()
         ->with(Mockery::type('array'))
         ->andReturn($user);
});

๐Ÿ”’ Security Issues โ€‹

Mass Assignment Vulnerability โ€‹

Problem: All attributes can be set, including protected ones.

php
<?php

// โŒ VULNERABLE
class User extends Model
{
    // No $fillable or $guarded defined
}

// Attacker can set is_admin!
User::create($request->all());

// โœ… SOLUTION
class User extends Model
{
    protected $fillable = [
        'name',
        'email',
        'password',
    ];
    
    // OR use $guarded
    protected $guarded = [
        'id',
        'is_admin',
        'created_at',
        'updated_at',
    ];
}

CSRF Token Mismatch โ€‹

Problem: AJAX requests failing with 419 error.

419 | Page Expired

Solution:

javascript
// Add CSRF token to AJAX headers
$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

// Or use Axios (Laravel includes this)
// resources/js/bootstrap.js
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = 
    document.querySelector('meta[name="csrf-token"]').getAttribute('content');
html
<!-- Add to blade layout -->
<meta name="csrf-token" content="{{ csrf_token() }}">

โšก Performance Issues โ€‹

Slow Queries โ€‹

Problem: Queries taking too long, timing out.

Debug:

php
<?php

use Illuminate\Support\Facades\DB;

// Enable query logging
DB::enableQueryLog();

// Your code
$users = User::with('posts')->get();

// See queries
$queries = DB::getQueryLog();
foreach ($queries as $query) {
    dump([
        'sql' => $query['query'],
        'time' => $query['time'] . 'ms',
    ]);
}

Solutions:

php
<?php

// 1. Add indexes
Schema::table('users', function (Blueprint $table) {
    $table->index('email');
    $table->index(['status', 'created_at']);
});

// 2. Use eager loading
$users = User::with(['posts', 'profile'])->get();

// 3. Select only needed columns
$users = User::select(['id', 'name', 'email'])->get();

// 4. Use pagination
$users = User::paginate(20);

Memory Limit Exceeded โ€‹

Problem: Fatal error: Allowed memory size exhausted.

Solutions:

php
<?php

// โŒ BAD: Loading everything
$users = User::all();  // 1 million users = crash

// โœ… GOOD: Use chunking
User::chunk(1000, function ($users) {
    foreach ($users as $user) {
        // Process
    }
});

// โœ… BETTER: Use lazy loading
User::lazy()->each(function ($user) {
    // Process one at a time
});

// โœ… GOOD: Use cursor
foreach (User::cursor() as $user) {
    // Memory efficient
}

๐Ÿ”ง Development Environment โ€‹

Vite Not Compiling Assets โ€‹

Problem: npm run dev errors or assets not updating.

Solutions:

bash
# 1. Clear node modules and reinstall
rm -rf node_modules package-lock.json
npm install

# 2. Clear Vite cache
rm -rf node_modules/.vite

# 3. Ensure vite.config.js is correct
# vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
    ],
});

# 4. Run dev server
npm run dev

Composer Memory Limit โ€‹

Problem: Composer update/install failing with memory error.

Solutions:

bash
# Temporary fix
php -d memory_limit=-1 /usr/local/bin/composer install

# Or set in php.ini
memory_limit = 512M

# Or use environment variable
COMPOSER_MEMORY_LIMIT=-1 composer install

๐Ÿ“‹ Quick Troubleshooting Checklist โ€‹

When something goes wrong:

bash
# 1. Clear all caches
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear

# 2. Regenerate autoload
composer dump-autoload

# 3. Check logs
tail -f storage/logs/laravel.log

# 4. Enable debug mode (local only!)
# .env
APP_DEBUG=true

# 5. Check Telescope
# Visit /telescope for request details

# 6. Run tests
php artisan test

# 7. Check migrations
php artisan migrate:status

๐Ÿ†˜ Getting Help โ€‹

Before Asking for Help โ€‹

  1. Check error logs - storage/logs/laravel.log
  2. Review recent changes - What changed before the error?
  3. Search documentation - Laravel docs, this guide
  4. Check Telescope - Request details, queries, exceptions
  5. Try in isolation - Create minimal reproduction

How to Ask for Help โ€‹

Provide:

markdown
## Issue Description
Clear description of the problem

## Expected Behavior
What should happen

## Actual Behavior
What actually happens

## Steps to Reproduce
1. Step one
2. Step two
3. Error occurs

## Environment
- Laravel Version: 10.x
- PHP Version: 8.2
- Database: MySQL 8.0
- OS: Ubuntu 22.04

## Error Message

Full error message with stack trace


## Code Sample
```php
// Relevant code

What I've Tried โ€‹

  • Cleared cache
  • Ran composer dump-autoload
  • etc.

---

<div class="maintenance-notice">
  <strong>๐Ÿ”ง Still Stuck?</strong> Don't hesitate to reach out to the team. Everyone encounters these issues - that's why we document them!
</div>

Built with VitePress