Published on 3/6/2024
My journey into the world of Laravel began with some client projects at my workplace, igniting a deep interest in the framework and its vibrant ecosystem. Fast forward nearly two years, and I'm still immersed in it, using Laravel for both work and personal projects. Laravel doesn't just come packed with a robust set of tools and features out of the box; its community has also cultivated an incredible ecosystem that further enhances its capabilities.
For those who are unaware, Laravel is an open-source PHP framework designed for building web applications. Originating from the mind of Taylor Otwell in 2011, it draws inspiration from the PHP framework Symfony. Following the MVC architectural pattern, Laravel prides itself on laying down the groundwork for developers, freeing them to focus on writing code without sweating the small stuff.
Comparable frameworks include Django in the Python world and Ruby on Rails.
Despite the prevailing sentiment in programming memes, coding in PHP offers an elegant experience, especially with the language's evolution since version 5. Even amidst working with frameworks like Vue and Next.js, I often find myself relishing the process of writing PHP over JavaScript (yes, even TypeScript).
Laravel has a plethora of reasons as to why it’s worth you picking up and trying, some of which include:
The Laravel team takes pride in its treasure trove of first-party packages catering to every developer's need. From server management with Forge to full-text model search with Scout and complete Stripe payment integration with Cashier, there's a package for everything. These packages are meticulously maintained, and the Laravel team consistently expands the roster of first-party supported packages in their library.
The best way to explore the vibrant ecosystem of Laravel is by diving into some code. We'll build a simple demo application that showcases multiple packages developed by the Laravel team, illustrating how seamlessly different parts of a project can be integrated.
Before diving in, here's what you'll need installed on your local machine:
We'll kick things off by creating a new Laravel application using Composer, and navigating to the project directory.
composer create-project laravel/laravel the-laravel-ecosystem
cd the-laravel-ecosystem
To ensure our application runs smoothly, we'll utilize Docker containers instead of local PHP and MySQL instances. Laravel Sail, which comes bundled with Laravel, makes this process a breeze. Initialize the Docker containers with:
php artisan sail:install
Choose the desired services when prompted by the terminal user interface (TUI). For this demo, we'll stick with a MySQL image.
Once Sail sets up the containers, start them with:
./vendor/bin/sail up -d
Note: With Laravel Sail installed, all Artisan commands will be prefixed with sail artisan ...
instead of php artisan...
While Laravel provides basic database migrations out of the box, we can kickstart our project with additional features using supported starter kits. For this demo, we'll use Laravel Breeze. Install it with:
composer require laravel/breeze --dev
Once installed, scaffold the starter kit code into your project.
sail artisan breeze:install
Choose Vue and Inertia as the stack options during the setup process.
After scaffolding, migrate the database, install frontend dependencies, and run the development server:
sail artisan migrate:fresh
npm install
npm run dev
Visit http://localhost
to see your application in action, courtesy of Laravel Breeze's starter kit.
Suppose you want to integrate OAuth authentication, say with GitHub. Laravel Socialite makes this process a breeze. Install Socialite with:
composer require laravel/socialite
For GitHub OAuth integration, create an OAuth application in your GitHub account's developer settings. Store the obtained keys in your project's .env
file or config/services.php
.
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GITHUB_CLIENT_REDIRECT=
'github' => [
'client_id' => env('GITHUB_CLIENT_ID'),
'client_secret' => env('GITHUB_CLIENT_SECRET'),
'redirect' => env('GITHUB_CLIENT_REDIRECT'),
]
Next, create endpoints to handle GitHub login and callback. Start by generating a new controller:
sail artisan make:controller GithubAuthController
The login
method in this controller redirects users to the GitHub login screen. This method is super simple as all it needs to do is utilize the Socialite package, set the driver got github
, and then call the redirect
method.
use Socialite;
public function login(): RedirectResponse
{
return Socialite::driver('github')->redirect();
}
The callback
method handles account creation and user authentication after successful GitHub login. This method will first use the Socialite package to parse the returned payload for user information, create or update that given user in our internal MySQL database, authenticate the user with Sanctum, and then redirect them back to the dashboard.
use App\\Models\\User;
use Socialite;
public function callback(): RedirectResponse
{
$githubUser = Socialite::driver('github')->user();
$user = User::updateOrCreate(
['email' => $githubUser->getEmail()]
[
'name' => $githubUser->getName(),
'password' => bcrypt($githubUser->getId())
]
);
auth()->login($user);
return to_route('dashboard');
}
Map these controller methods to endpoint URIs in web.php
:
use App\\Http\\Controllers\\GithubAuthController;
Route::get('/github/login', [GithubAuthController::class, 'login'])->name('github.login');
Route::get('/github/callback', [GithubAuthController::class, 'callback'])->name('github.callback');
Cache the routes with sail artisan route:cache
and visit the endpoints in your application to test GitHub login.
Imagine you want to set up a billing page for your users and offer a fantastic product for sale. Enter Laravel Cashier – your ticket to seamless Stripe payment integration. Get Cashier up and running with:
composer require laravel/cashier
For Stripe integration, you'll need to create a Stripe account and obtain your secret keys along with the Price ID for the product you're selling. Add these values to your .env
file:
STRIPE_KEY=
STRIPE_SECRET=
STRIPE_PRICE_ID=
Cashier requires database migrations to work smoothly. Scaffold these migrations into your project and run them:
sail artisan vendor:publish --tag="cashier-migrations"
sail artisan migrate:fresh
To make the most of Stripe integration, add the Billable
trait provided by Cashier to your User
model:
use Cashier\\Billable;
class User extends Model
{
use Billable;
}
Now, let's tweak the GitHub OAuth logic to create the retrieved user as a customer in our Stripe account if they're not already. Utilize the createAsStripeCustomer
method from the Billable
trait:
use App\\Models\\User;
use Socialite;
public function callback(): RedirectResponse
{
$githubUser = Socialite::driver('github')->user();
$user = User::updateOrCreate(
['email' => $githubUser->getEmail()]
[
'name' => $githubUser->getName(),
'password' => bcrypt($githubUser->getId())
]
);
if (!$user->stripe_id) {
$user->createAsStripeCustomer();
}
auth()->login($user);
return to_route('dashboard');
}
Let's provide users with a billing portal and a way to purchase our product. Start by creating a new controller:
sail artisan make:controller BillingController
The billingPortal
method in this controller will use Laravel Cashier to redirect the authenticated user to an external Stripe billing portal dashboard:
use Illuminate\\Http\\Request;
public function billingPortal(Request $request)
{
return $request->user()->redirectToBillingPortalUrl(route('dashboard'));
}
The checkout
method in this controller will use Laravel Cashier, along with the Stripe Price ID, to redirect the user to an external Stripe checkout page:
public function checkout()
{
return Checkout::guest()
->create([env('STRIPE_PRICE_ID')], [
'success_url' => route('dashboard'),
'cancel_url' => route('dashboard')
]);
}
Map these controller methods to endpoint URIs in web.php
:
Route::get('/billing', [BillingController::class, 'billingPortal'])->name('billing');
Route::get('/checkout', [BillingController::class, 'checkout'])->name('checkout');
Cache the routes with sail artisan route:cache
and visit the endpoints in your application to test the Stripe integration.
In under an hour, with just a few code additions, our application boasts:
This is merely scratching the surface of what the Laravel ecosystem offers. Our demo taps into just seven of the 24 packages highlighted on the official documentation website. With Laravel, the sky's the limit for what you can achieve in your projects.