Laravel Fundamentals: A Cheat Sheet for Rapid Development
Tags: webdev, laravel, beginners, php
Published: 2024-04-11 11:19:31

## Laravel Directory Structure Overview:

- **app**: Contains the core application code, including models, controllers, middleware, and other PHP classes specific to your application.
- **bootstrap**: Contains the application bootstrap files, including the app.php file which initializes the Laravel framework.
- **config**: Stores configuration files for various aspects of the application, such as database connections, session settings, and app-specific configurations.
- **database**: Contains database-related files, including migrations, seeders, and factories. Migrations are used to modify the database schema, while seeders populate the database with sample data. Factories are used to generate fake data for testing purposes.
- **public**: The public directory is the web server's document root and contains the entry point for all web requests (index.php). It also holds publicly accessible assets such as images, stylesheets, and JavaScript files.
- **resources**: Contains assets that are used to build the application, such as views, language files, and front-end assets like CSS and JavaScript. This directory is often further divided into views, lang, and assets subdirectories.
- **routes**: Contains the application's route definitions. Routes define how incoming requests are handled and mapped to controllers or closures.
- **storage**: Stores temporary files generated by the application, such as log files, cached files, and session files. It also contains directories for framework-generated files like compiled Blade views and cached configuration files.
- **tests**: Contains automated tests for the application, including unit tests, feature tests, and browser tests.
- **vendor**: Contains dependencies installed via Composer, including Laravel itself and third-party packages.

## Basic Artisan commands commonly used in Laravel development

`php artisan make:model`

Example: `php artisan make:model Post`
Explanation: Creates a new Eloquent model class (`Post.php`) in the app directory. Models represent data structures in your application and are typically used to interact with your database tables.

`php artisan make:middleware`

Example: `php artisan make:middleware Authenticate`
Explanation: Creates a new middleware class (`Authenticate.php`) in the `app/Http/Middleware` directory. [Middleware](https://spacema-dev.com/navigating-laravel-middleware-enhancing-your-applications-security-and-functionality/) provides a convenient mechanism for filtering HTTP requests entering your application.

`php artisan make:migration`

Example: `php artisan make:migration create_users_table`
Explanation: Creates a new migration file in the `database/migrations` directory. Migrations are used to modify the database schema and are essential for version controlling your database schema changes.

`php artisan make:seeder`

Example: `php artisan make:seeder UsersTableSeeder`
Explanation: Creates a new database seeder class (`UsersTableSeeder.php`) in the `database/seeders` directory. Seeders are used to populate your database with dummy data for testing and development.

`php artisan route:list`

Example: `php artisan route:list`
Explanation: Lists all registered routes for your application. This command provides a quick overview of the routes defined in your routes/web.php and routes/api.php files along with their associated HTTP methods and URIs.

## Different Route Types (GET, POST, PUT, DELETE)

**GET Route:**

Used for retrieving resources.

Example:
```php
Route::get('/posts', 'PostController@index');
```

**POST Route:**

Used for submitting data to the server.

Example:

```php
Route::post('/posts', 'PostController@store');
```

**PUT/PATCH Route:**

Used for updating existing resources.

Example:

```php
Route::put('/posts/{id}', 'PostController@update');
```

**DELETE Route:**

Used for deleting resources.

Example:

```php
Route::delete('/posts/{id}', 'PostController@destroy');
```

## Laravel Route Parameters and Named Routes

**Route Parameters:**

Allow dynamic parts in the URI.
Enclosed in curly braces {}.

Example:

```php
Route::get('/posts/{id}', 'PostController@show');
```

**Named Routes:**

Provide a convenient way to refer to routes by name.
Defined using the name method.

Example:

```php
Route::get('/posts/{id}', 'PostController@show')->name('posts.show');
```

## Middleware Usage

**Global Middleware:**

Applied to all routes.
Defined in the `$middleware` property of `App\Http\Kernel`.

Example:

```php
protected $middleware = [
    // ...
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    // ...
];
```

**Route Middleware:**

Applied to specific routes or route groups.
Defined in the `$routeMiddleware` property of `App\Http\Kernel`.

Example:

```php
protected $routeMiddleware = [
    // ...
    'auth' => \App\Http\Middleware\Authenticate::class,
    'admin' => \App\Http\Middleware\AdminMiddleware::class,
    // ...
];
```

Applied using the middleware method in route definition.

Example:

```php
Route::get('/admin/dashboard', 'AdminController@dashboard')->middleware('admin');
```

**Inline Middleware:**

Applied inline within route definition.

Example:

```php
Route::get('/profile', function () {
    // Logic here
})->middleware('auth');
```

Middleware allows you to intercept HTTP requests entering your application and perform actions such as authentication, authorization, logging, etc. 


## Model Creation and Relationships

**Model Creation**

Models in Laravel typically reside in the app directory and extend the Illuminate\Database\Eloquent\Model class.

Example:

```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}
```

**Relationships**

Eloquent supports various types of relationships such as hasOne, hasMany, belongsTo, belongsToMany, etc.

Example:

```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}
```

## CRUD Operations with Eloquent

**Create**

Use the create method to insert a new record into the database.

Example:

```php
$post = Post::create([
    'title' => 'New Post',
    'content' => 'This is a new post content.',
]);
```

**Read**

Use methods like all, find, findOrFail, where, get, etc., to retrieve records from the database.

Example:

```php
$posts = Post::all();
$post = Post::find($id);
```

**Update**

Use the update method to update existing records.

Example

```php
$post = Post::find($id);
$post->update([
    'title' => 'Updated Title',
    'content' => 'Updated content.',
]);
```

**Delete**

Use the delete method to remove records from the database.

Example:

```php
$post = Post::find($id);
$post->delete();
```

## Model Scopes and Query Builders

**Model Scopes**

Model scopes are query modifiers that allow you to encapsulate common queries.
Define scopes as methods in your model.

Model scopes are methods defined within your Eloquent model classes. These methods typically return an instance of the `Illuminate\Database\Eloquent\Builder` class, which represents the query builder for the model. You can define any custom query constraints within these methods, and they can be chained onto queries just like any other query builder method.

Let's say we have a Post model and we want to create a scope to retrieve only published posts. We can define a scope method named published within the Post model:

Example:

```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function scopePublished($query)
    {
        return $query->where('published', true);
    }
}
```

Usage

```php
$publishedPosts = Post::published()->get();
```

**Query Builders**

Eloquent also provides query builder methods for building complex queries.

Example:

```php
$posts = Post::where('published', true)
             ->orderBy('created_at', 'desc')
             ->take(10)
             ->get();
```

## Form Request Validation Rules

**Form Request Validation**

Laravel provides a convenient way to validate incoming HTTP requests using Form Request classes.

These classes contain validation rules and authorize logic to validate incoming requests before they reach your controller.

Example of creating a Form Request class:

```
php artisan make:request StorePostRequest
```

This command creates a new Form Request class named `StorePostRequest` in the `app/Http/Requests` directory.

**Defining Validation Rules**

Inside the generated Form Request class, you define your validation rules using the rules method.

Example:

```php
public function rules()
{
    return [
        'title' => 'required|string|max:255',
        'content' => 'required|string',
    ];
}
```
In this example, we define rules for the title and content fields of the form.

**Customizing Error Messages**

You can customize error messages for validation rules by adding a messages method to your **Form Request class**.

Example:

```
public function messages()
{
    return [
        'title.required' => 'The title field is required.',
        'content.required' => 'The content field is required.',
    ];
}
```
This allows you to provide more user-friendly error messages.


## Error Handling and Flash Messages

**Error Handling**

Laravel automatically redirects back to the previous page with validation errors flashed to the session if validation fails.

You can display these errors in your views using the errors helper.

Example:

```php
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
```
This displays a list of validation errors if there are any.

**Flash Messages**

Flash messages are temporary messages that are stored in the session and displayed to the user on the next request.
You can flash messages to the session using the with method on redirect responses.

Example:

```php
return redirect()->route('posts.index')->with('success', 'Post created successfully!');
```

This flashes a success message to the session, which you can then display to the user on the redirected page.


## User Model and Laravel Authentication

**User Model**

Laravel includes a User model out-of-the-box, typically located at `app\Models\User.php`.

This model represents users in your application and is used for authentication purposes.

**Laravel Authentication**

Laravel provides a robust authentication system out-of-the-box, including routes, controllers, and views for login, registration, password reset, and email verification.

You can generate the authentication scaffolding using the `make:auth Artisan` command:

```php
php artisan make:auth
```

This command creates routes, controllers, and views necessary for authentication.

**Authentication Methods**

Laravel provides various methods for authenticating users, including session-based authentication, token-based authentication (e.g., API tokens), and OAuth integration.

Session-based authentication is the default method and uses Laravel's session and cookie system to manage user authentication.

## Gate Definition for Authorization Checks

Gate Definition:

Laravel's Gate system provides a simple, expressive way to define authorization checks.

Gates are defined using the `Gate::define` method within the `AuthServiceProvider`.

Example:

```php
use Illuminate\Support\Facades\Gate;

public function boot()
{
    $this->registerPolicies();

    Gate::define('update-post', function ($user, $post) {
        return $user->id === $post->user_id;
    });
}
```

In this example, we define a Gate named update-post that checks if the authenticated user is the owner of the post.

**Using Gates**

Once gates are defined, you can check them anywhere in your application using the Gate facade or the `@can` Blade directive.

Example:

```php
if (Gate::allows('update-post', $post)) {
    // Allow user to update the post
}
```

Example using Blade directive:

```
@can('update-post', $post)
    <!-- Display edit button -->
@endcan
```

These checks allow you to control access to specific actions or resources based on user roles or permissions

## Benefits of Laravel's Authentication and Authorization

**Ease of Use**

Laravel's authentication and authorization features are straightforward to set up and use, requiring minimal configuration for common use cases.

**Security**

Laravel's authentication system is secure by default, employing best practices such as password hashing and protection against [CSRF attacks](https://spacema-dev.com/what-is-cross-site-request-forgery-csrf/).

**Flexibility**

Laravel provides flexibility in defining authorization checks using Gates, allowing you to define complex rules based on user roles, permissions, and resource ownership.

**Integration**

Laravel's authentication system seamlessly integrates with other Laravel features such as middleware, route protection, and Blade directives.


## Events and Listeners

**Events**

Events are a way of signaling that something has happened within your application.

You can define events as classes that extend Laravel's `Illuminate\Foundation\Events\Dispatchable` class.

Example:

```php
namespace App\Events;

use Illuminate\Foundation\Events\Dispatchable;

class OrderShipped
{
    use Dispatchable;

    public $order;

    public function __construct($order)
    {
        $this->order = $order;
    }
}
```

**Listeners**

Listeners are responsible for responding to events.
Listeners can be defined as classes or closures.

Example (class-based listener):

```php
namespace App\Listeners;

use App\Events\OrderShipped;

class SendShipmentNotification
{
    public function handle(OrderShipped $event)
    {
        // Logic to send shipment notification
    }
}
```

## Queues and Jobs

**Queues**

Queues allow you to defer time-consuming tasks in your application to be processed asynchronously.

Laravel supports various queue drivers like database, Redis, Amazon SQS, etc.

Example:

```php
dispatch(function () {
    // Logic to process the job
});
```

**Jobs**

Jobs are classes that encapsulate the logic of a queued task.
They should implement the `Illuminate\Contracts\Queue\ShouldQueue` interface.

Example:

```php
namespace App\Jobs;

class ProcessOrder implements ShouldQueue
{
    public function handle()
    {
        // Logic to process the order
    }
}
```

## Caching with Laravel

**Cache Configuration**

Laravel provides a unified API for various caching systems such as Redis, Memcached, and database.

Cache configuration is defined in the `config/cache.php` file.
Cache Usage:

[Laravel's Cache facade](https://laravel.com/docs/11.x/cache) provides convenient methods for caching data.

Example:

```php
$value = Cache::remember('users', 60, function () {
    return DB::table('users')->get();
});
```

## Unit Testing with Laravel

**PHPUnit Integration**

Laravel integrates with [PHPUnit](https://phpunit.de/index.html) for unit testing out-of-the-box.
Tests are stored in the tests directory of your Laravel application.

**Testing Features**

Laravel provides various helpers and assertions for testing routes, controllers, models, and more.

Example:

```php
public function testBasicTest()
{
    $response = $this->get('/');

    $response->assertStatus(200);
}
```
**Testing Database**

Laravel provides utilities for testing database interactions using in-memory SQLite database.

In Laravel, testing database interactions is an essential aspect of unit testing. 
Laravel provides utilities to facilitate testing database-related functionalities using an in-memory SQLite database, which allows for fast and efficient testing without affecting the actual database used in development or production environments.

Example:

```php
public function testDatabase()
{
    $user = User::factory()->create();

    $this->assertDatabaseHas('users', [
        'email' => $user->email,
    ]);
}
```

Explanation

In this example, a new user record is created using Laravel's model factory method `User::factory()->create()`.
The User model factory generates dummy data for the user and inserts it into the database.

The `assertDatabaseHas` method is used to assert that a given record exists in the database table.

It takes two parameters: the name of the database table (`users` in this case) and an array of conditions that the record must meet to pass the assertion.
In this example, we are asserting that there is a record in the `users` table where the email column matches the email address of the user created in the previous step (`$user->email`).


Read also:
[Laravel](https://laravel.com/docs/11.x/installation)
[How To CRUD (Create, Read, Update, and Delete) With Laravel](https://kinsta.com/blog/laravel-crud/)
[What are Facades in Laravel](https://spacema-dev.com/what-are-facades-in-laravel-and-why-do-we-use-them/)
[Laravel tutorials](https://www.digitalocean.com/community/tags/laravel)
[A Guide to Laravel Blade](https://mikevaren.hashnode.dev/a-guide-to-laravel-blade)