Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
- Simple, fast routing engine.
- Powerful dependency injection container.
- Multiple back-ends for session and cache storage.
- Expressive, intuitive database ORM.
- Database agnostic schema migrations.
- Robust background job processing.
- Real-time event broadcasting.
Laravel is accessible, powerful, and provides tools required for large, robust applications.
Laravel has the most extensive and thorough documentation and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
In addition, Laracasts contains thousands of video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
You can also watch bite-sized lessons with real-world projects on Laravel Learn, where you will be guided through building a Laravel application from scratch while learning PHP fundamentals.
Laravel's predictable structure and conventions make it ideal for AI coding agents like Claude Code, Cursor, and GitHub Copilot. Install Laravel Boost to supercharge your AI workflow:
composer require laravel/boost --dev
php artisan boost:installBoost provides your agent 15+ tools and skills that help agents build Laravel applications while following best practices.
heif-convert (libheif 1.19+) is required on the server for HEIC/HEIF image support (iPhone photo uploads):
# Install build dependencies
sudo apt-get install cmake build-essential libde265-dev libjpeg-dev libpng-dev libheif-examples
# Compile libheif 1.19+ from source (Ubuntu's default version is too old)
cd /tmp
git clone --depth 1 --branch v1.21.2 https://github.com/strukturag/libheif.git
cd libheif && mkdir build && cd build
cmake --preset=release ..
make -j$(nproc)
sudo make install
sudo ldconfigVerify the installation:
# Binary path + libheif version (expect 1.19+)
which heif-convert
heif-convert --version | head -1
pkg-config --modversion libheif
# Sanity-check a real HEIC file
heif-convert /path/to/photo.heic /tmp/out.jpg && file /tmp/out.jpgConfirm that PHP sees the binary (restart PHP-FPM after ldconfig if which is empty inside PHP):
php artisan tinker --execute 'dump(trim(shell_exec("which heif-convert")), trim(shell_exec("heif-convert --version 2>&1 | head -1")));'MediaUploadService uses heif-convert to convert HEIC photos to JPEG because the PHP Imagick extension and ImageMagick 6.x cannot reliably decode iPhone HEIC files with HDR gain maps.
Posts store the GPS coordinates extracted from photo EXIF in a geography(Point, 4326) column on the posts table. PostGIS must be installed and enabled on every Postgres database the app talks to.
-
SSH into the Forge server and install PostGIS for the matching Postgres major version:
psql --version # e.g. PostgreSQL 16.x sudo apt-get update sudo apt-get install -y postgresql-16-postgis-3 # match the major version
-
Enable the extension on the site database (one-time):
sudo -u postgres psql -d production -c "CREATE EXTENSION IF NOT EXISTS postgis;" sudo -u postgres psql -d production -c "SELECT PostGIS_Version();"
-
Run pending migrations from the site directory:
cd /home/forge/<site> php artisan migrate --force
The enable_postgis_extension migration runs CREATE EXTENSION IF NOT EXISTS postgis and is idempotent. The migration requires a superuser role (the default Forge forge role qualifies); if it fails with permission denied to create extension, run step 2 once manually as postgres and re-run the migration.
Herd's bundled Postgres works the same way:
psql -U root -d innerr -c "CREATE EXTENSION IF NOT EXISTS postgis;"
php artisan migratepsql -U <user> -d <db> -tAc "SELECT extname || ' ' || extversion FROM pg_extension WHERE extname='postgis'"
psql -U <user> -d <db> -tAc "SELECT column_name, udt_name FROM information_schema.columns WHERE table_name='posts' AND column_name IN ('taken_at','coordinates') ORDER BY column_name"
psql -U <user> -d <db> -tAc "SELECT indexname FROM pg_indexes WHERE tablename='posts' AND indexname='posts_coordinates_gist'"You should see postgis 3.x, both EXIF columns (taken_at timestamp, coordinates geography), and the GiST index name.
Tests run against a dedicated Postgres database with PostGIS enabled (the spatial functions used by EXIF post coordinates do not exist in SQLite). One-time local setup:
psql -U root -d postgres -c "CREATE DATABASE innerr_test;"
psql -U root -d innerr_test -c "CREATE EXTENSION postgis;"Then run tests as usual:
php artisan test --compactThe DB connection is wired up in phpunit.xml; RefreshDatabase re-runs migrations into the clean schema for each test class.
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the Laravel documentation.
In order to ensure that the Laravel community is welcoming to all, please review and abide by the Code of Conduct.
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via taylor@laravel.com. All security vulnerabilities will be promptly addressed.
The Laravel framework is open-sourced software licensed under the MIT license.