A new hire sets up your Laravel 13 veterinary-clinic booking app on a fresh laptop with PHP 8.2; what goes wrong, and how do you fix it?
answer
- platform requirements, not a Laravel bug
- php ^8.3 in framework and skeleton
- create-project quietly picks an older major
- ext-mbstring, openssl, tokenizer and friends
- pdo_sqlite for the SQLite default
basics
~20 sLaravel 13 requires PHP 8.3, so composer install on the cloned app fails its platform check, and a fresh laravel new or create-project quietly resolves Laravel 12 instead. Install PHP 8.3+ with the required extensions, including pdo_sqlite, then rerun setup.
solid answer
~40 s`laravel/framework` 13 and the skeleton both require `php: ^8.3`, and the framework also requires the `ctype`, `filter`, `hash`, `mbstring`, `openssl`, `session` and `tokenizer` extensions. On PHP 8.2, `composer install` in the cloned repository stops because the lock file's packages need a newer PHP. The quieter failure is a new project: `composer create-project laravel/laravel` (and `laravel new`, which calls it) picks the newest skeleton the local PHP can install, so the hire silently gets Laravel 12 code and docs that do not match the team's. Fix the environment rather than the check: install PHP 8.3 or newer (Herd or the php.new script), confirm with `php -v` and `php -m`, and add `pdo_sqlite` because the skeleton defaults to SQLite. Then `composer run setup` and `composer run dev`. Never bypass it with `--ignore-platform-reqs`.
code
bash · 9 linesphp -v # must report 8.3 or newer
php -m | grep -i -E 'mbstring|openssl|tokenizer|pdo_sqlite'
git clone [email protected]:clinic/vet-clinic.git
cd vet-clinic
composer run setup # install, .env, key, migrate, npm build
composer run dev
php artisan --version # confirm the major you actually gotgo deeper
Remember that Laravel 13 needs PHP 8.3 or newer plus a handful of extensions, and check php -v before anything else.
Explain Composer's platform check on install, the required ext- entries in the framework, and why the SQLite default needs pdo_sqlite.
Diagnose the silent case, where create-project resolves an older major, and make onboarding repeatable with a pinned PHP version and a setup script.
Set a team policy for the PHP version across laptops, CI and production, and schedule PHP upgrades ahead of each Laravel major's floor.
## The scenario A new developer joins the team that builds a **veterinary-clinic booking app** on Laravel 13. Their laptop came with PHP 8.2. They try two things: cloning the app, and creating a scratch project to experiment. Both go wrong, in different ways, and the difference is what interviewers want you to explain. ## What Laravel 13 requires - **PHP 8.3 or newer.** `laravel/framework` 13 and the `laravel/laravel` skeleton both declare `"php": "^8.3"`; the release table lists PHP 8.3 to 8.5 for Laravel 13. - **Extensions** declared by the framework's `composer.json`: `ext-ctype`, `ext-filter`, `ext-hash`, `ext-mbstring`, `ext-openssl`, `ext-session` and `ext-tokenizer`. The Laravel installer checks the same seven before it creates anything. - **Server requirements** in the deployment docs add cURL, DOM, Fileinfo, PCRE, PDO and XML. - **A PDO driver for your database.** The skeleton's `.env.example` sets `DB_CONNECTION=sqlite`, so `pdo_sqlite` is needed on day one. ## Failure 1: the cloned app `composer install` reads `composer.lock`, which pins exact versions resolved on a newer PHP. Composer checks **platform requirements** (the PHP version and `ext-*` entries) before installing and refuses when they are not met, naming the package and the PHP constraint. This failure is loud, which is good. ## Failure 2: the scratch project `composer create-project laravel/laravel sandbox` without a version constraint asks Composer for the **best candidate installable on this PHP**. On PHP 8.2 that is the newest Laravel 12 skeleton, not 13. `laravel new` runs the same step, so it behaves the same way. Nothing errors: the hire just learns Laravel 12 APIs and docs while the team writes Laravel 13 code. Check `php artisan --version` in anything you create. ## Reading the error messages The two failures look different on screen, which helps you tell them apart quickly: - The clone fails inside **Composer**, before any Laravel code runs, with a message that the lock file's packages require a PHP version the machine does not have, naming `laravel/framework` or another package and its `php` constraint. - A missing extension shows the same way, naming the `ext-*` requirement, for example `ext-mbstring`. - The Laravel installer, run interactively, stops earlier with its own message: "The following PHP extensions are required but are not installed", followed by the list. - A missing `pdo_sqlite` usually surfaces later, as a "could not find driver" database error during the first migration. - The scratch project shows **no error**; only `php artisan --version` reveals the older major. ## The fix, in order 1. Install PHP 8.3 or newer. Herd bundles PHP on macOS and Windows; the documented php.new script installs PHP, Composer and the installer on macOS, Windows or Linux. 2. Confirm with `php -v` and list extensions with `php -m`; install any missing one (`pdo_sqlite` is the usual gap on a minimal Linux build). 3. Match the team's PHP version, not just the floor. A lock file resolved on PHP 8.4 can contain packages that require 8.4, so 8.3 may still fail. 4. Run the skeleton's `composer run setup` script: `composer install`, copy `.env.example` to `.env`, `key:generate`, `migrate --force`, `npm install --ignore-scripts` and `npm run build`. 5. Start the loop with `composer run dev`, or open the `.test` URL if the folder is parked on Herd or Valet. ## What not to do | Tempting shortcut | Why it hurts | |---|---| | `composer install --ignore-platform-reqs` | Installs code that uses PHP 8.3 syntax and functions, which then fails at runtime | | Pinning an old Laravel to match the laptop | Splits the team across majors and support windows | | Editing the `php` constraint in `composer.json` | Lies to Composer about what the framework needs | ## Making onboarding repeatable - Write the required PHP version and extensions into the README, next to the one-line `composer run setup`. - Pin the version where the local tool reads it, for example `valet isolate [email protected]` for a Valet site. - Have CI run on the same PHP minor as production so the lock file is resolved against a known platform.
- Why is the scratch project on PHP 8.2 more dangerous than the failing clone?The clone fails loudly: Composer refuses the lock file and names the PHP constraint. The scratch project succeeds: `create-project` picks the newest skeleton that PHP 8.2 can install, which is Laravel 12, so nothing warns the hire that they are practising against a different major. Only `php artisan --version` or `composer.json` reveals it.
- What does the skeleton's composer run setup script do, and when does it help?It runs `composer install`, copies `.env.example` to `.env` if missing, runs `key:generate` and `migrate --force`, then `npm install --ignore-scripts` and `npm run build`. It turns a fresh clone into a working app in one command once the platform is right, but it cannot fix a PHP version or a missing extension.
saying these in an interview costs you the question
- Laravel 13 still runs on PHP 8.2 with a warning
- Use --ignore-platform-reqs to get past the PHP check
- laravel new always installs the latest Laravel whatever the PHP version
- The SQLite default needs no PHP extension
- A missing extension only matters in production, not locally