- Introduction
- Setting Up Laravel
- Database Configuration
- Creating the URL Model and Migration
- Building the Controller
- Setting Up Routes
- Creating Views
- Generating Short URLs
- Handling Redirections
- Implementing Custom Middleware
- Testing Your Application
- Deploying the Application
- Conclusion
Creating a URL shortener service is a fantastic way to dive into web application development with Laravel, one of the most popular PHP frameworks. This tutorial will guide you through setting up a basic URL shortener, from initializing the project to deploying it. We will cover everything you need, including setting up routes, controllers, models, and views, as well as integrating database functionality.
Introduction
A URL shortener takes a long URL and provides a shorter, unique URL that redirects to the original URL. These services are handy for social media, SMS messages, and any situation where a shorter URL is more convenient. In this tutorial, we will build a simple URL shortener service using Laravel.
Setting Up Laravel
First, ensure you have Composer installed on your system. Composer is a dependency manager for PHP. If you don’t have it installed, you can download it from getcomposer.org.
-
Install Laravel via Composer:
composer create-project --prefer-dist laravel/laravel url-shortener
-
Navigate to the project directory:
cd url-shortener
-
Serve the application:
php artisan serve
Your Laravel application should now be running on
http://127.0.0.1:8000
.
Database Configuration
We need to set up the database connection. Laravel supports various database systems; we will use MySQL for this tutorial.
-
Create a database: Create a new database using your preferred method (e.g., phpMyAdmin, MySQL Workbench, or command line).
-
Configure the
.env
file: Update the database configuration in the.env
file:DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=url_shortener DB_USERNAME=root DB_PASSWORD=your_password
Creating the URL Model and Migration
Laravel’s Eloquent ORM makes it easy to interact with your database. We will create a model for our URLs along with a migration to create the database table.
-
Generate the model and migration:
php artisan make:model Url -m
-
Define the migration: Open the migration file in
database/migrations/
and update theup
method:public function up() { Schema::create('urls', function (Blueprint $table) { $table->id(); $table->string('original_url'); $table->string('short_url')->unique(); $table->timestamps(); }); }
-
Run the migration: Apply the migration to create the
urls
table in your database:php artisan migrate
Building the Controller
The controller will handle the logic for creating and managing short URLs.
-
Generate the controller:
php artisan make:controller UrlController
-
Define the controller methods: Open
app/Http/Controllers/UrlController.php
and define the methods for displaying the form, creating the short URL, and redirecting to the original URL.namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Url; use Illuminate\Support\Str; class UrlController extends Controller { // Display the form for creating a new short URL public function index() { return view('url.index'); } // Store a new short URL public function store(Request $request) { $request->validate([ 'original_url' => 'required|url' ]); $url = new Url(); $url->original_url = $request->original_url; $url->short_url = Str::random(6); $url->save(); return redirect()->route('url.show', $url->short_url); } // Redirect to the original URL public function show($short_url) { $url = Url::where('short_url', $short_url)->firstOrFail(); return redirect($url->original_url); } }
Setting Up Routes
Next, we need to define the routes for our URL shortener.
-
Open
routes/web.php
and add the following routes:use App\Http\Controllers\UrlController; Route::get('/', [UrlController::class, 'index'])->name('url.index'); Route::post('/shorten', [UrlController::class, 'store'])->name('url.store'); Route::get('/{short_url}', [UrlController::class, 'show'])->name('url.show');
Creating Views
We will create views to display the form for creating new short URLs and showing the shortened URL.
-
Create a directory for views: Inside
resources/views
, create a folder namedurl
. -
Create
index.blade.php
: This view will contain the form for submitting a new URL.<!-- resources/views/url/index.blade.php --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>URL Shortener</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> </head> <body> <div class="container mt-5"> <h1 class="text-center">URL Shortener</h1> <form action="{{ route('url.store') }}" method="POST"> @csrf <div class="form-group"> <label for="original_url">Enter URL:</label> <input type="url" name="original_url" class="form-control" required> </div> <button type="submit" class="btn btn-primary">Shorten URL</button> </form> </div> </body> </html>
-
Create
show.blade.php
: This view will display the shortened URL.<!-- resources/views/url/show.blade.php --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>URL Shortener</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> </head> <body> <div class="container mt-5"> <h1 class="text-center">URL Shortener</h1> <p class="text-center"> Your shortened URL is: <a href="{{ route('url.show', $url->short_url) }}"> {{ route('url.show', $url->short_url) }} </a> </p> </div> </body> </html>
Generating Short URLs
We use Laravel's Str::random()
method to generate random strings for our short URLs. This method ensures that our URLs are unique and of the specified length.
In the store
method of the UrlController
, we generate a random string of six characters:
$url->short_url = Str::random(6);
Handling Redirections
The show
method in the UrlController
handles the redirection. It fetches the original URL from the database using the provided short URL and redirects the user to it.
public function show($short_url)
{
$url = Url::where('short_url', $short_url)->firstOrFail();
return redirect($url->original_url);
}
Implementing Custom Middleware
Middleware in Laravel can be used to handle various tasks, such as authentication, logging, or input validation. We can create custom middleware to log URL accesses.
-
Generate middleware:
php artisan make:middleware LogUrlAccess
-
Define the middleware logic: Open
app/Http/Middleware/LogUrlAccess.php
and update thehandle
method:namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; class LogUrlAccess { public function handle(Request $request, Closure $
next) { $short_url = $request->route('short_url'); Log::info('Short URL accessed:', ['short_url' => $short_url]); return $next($request); } }
3. **Register the middleware:** Open `app/Http/Kernel.php` and add the middleware to the `$routeMiddleware` array:
```php
protected $routeMiddleware = [
// Other middleware...
'log.url.access' => \App\Http\Middleware\LogUrlAccess::class,
];
-
Apply the middleware to the route: Open
routes/web.php
and apply the middleware to the route that handles redirection:Route::get('/{short_url}', [UrlController::class, 'show']) ->name('url.show') ->middleware('log.url.access');
Testing Your Application
Testing is crucial to ensure your application works as expected. Laravel provides robust testing tools out of the box.
-
Create a test for URL shortening: Open
tests/Feature/UrlShortenerTest.php
and write the following test:namespace Tests\Feature; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; use App\Models\Url; class UrlShortenerTest extends TestCase { use RefreshDatabase; /** @test */ public function it_can_shorten_a_url() { $response = $this->post('/shorten', [ 'original_url' => 'https://www.example.com' ]); $response->assertStatus(302); $this->assertDatabaseHas('urls', [ 'original_url' => 'https://www.example.com' ]); } /** @test */ public function it_redirects_to_original_url() { $url = Url::create([ 'original_url' => 'https://www.example.com', 'short_url' => 'abc123' ]); $response = $this->get('/abc123'); $response->assertRedirect('https://www.example.com'); } }
-
Run the tests:
php artisan test
Ensure all tests pass to verify the functionality of your URL shortener.
Deploying the Application
Once your application is built and tested, it's time to deploy it. Here are the steps for deploying a Laravel application to a production server.
-
Choose a hosting provider: Some popular options include AWS, DigitalOcean, and Heroku. For this tutorial, we'll use Laravel Forge, a service that simplifies deploying Laravel applications.
-
Set up Laravel Forge:
- Sign up for a Laravel Forge account.
- Connect your server provider (e.g., DigitalOcean).
- Create a new server and configure it with your domain.
-
Deploy your application:
- Link your Forge account to your GitHub repository containing the URL shortener project.
- Configure the deployment script to run migrations and other necessary commands.
- Deploy the application through the Forge dashboard.
-
Set up environment variables: Ensure that your
.env
file on the server contains the correct database and application settings.
Conclusion
Building a URL shortener service with Laravel is a great way to learn about web development and the features of this powerful PHP framework. We covered the entire process, from setting up the project to deploying it, including:
- Setting up a Laravel project
- Configuring the database
- Creating models, controllers, and views
- Generating short URLs
- Handling redirections
- Implementing custom middleware
- Testing the application
- Deploying to a production server
With this knowledge, you can further enhance your URL shortener by adding features like user authentication, analytics, or custom URL aliases.
Interested in proving your knowledge of this topic? Take the PHP Fundamentals certification.
PHP Fundamentals
Covering the required knowledge to create and build web applications in PHP.
$99