Question
I am running Laravel 4 migrations on macOS with Artisan, but I receive this error:
Laravel requires the Mcrypt PHP extension.
I believe the Mcrypt extension is enabled in my PHP configuration. Why does Laravel still report that it is missing, and how can I identify and fix the configuration problem?
Short Answer
This page explains how PHP extensions are loaded, why Laravel 4 checks for Mcrypt, and why the PHP used by the command line can differ from the PHP used by a web server. You will learn how to inspect the active PHP binary and configuration file, verify whether Mcrypt is actually loaded, and choose an appropriate fix for an older Laravel application.
Concept
Laravel 4 historically depended on the Mcrypt PHP extension for encryption-related functionality. Before running commands such as migrations, Laravel checks whether required extensions are available. If Mcrypt is not loaded by the PHP process running Artisan, Laravel stops with the requirement error.
The important detail is that enabling an extension in a php.ini file is not enough. PHP can run in different environments:
- CLI PHP: the PHP executable used by
php artisan migrate. - Web-server PHP: PHP used through Apache, Nginx with PHP-FPM, or another server integration.
- Different installations: macOS system PHP, Homebrew PHP, MAMP/XAMPP PHP, and version-manager PHP can all coexist.
Each installation or environment may use a different executable and a different configuration file. Since php artisan migrate runs in the terminal, the CLI PHP configuration is the one that matters.
Mcrypt is also a legacy technology. It was deprecated in PHP 7.1 and removed from core PHP distributions in PHP 7.2. Laravel 4 is an old framework release, so maintaining it may require an older compatible PHP environment or, preferably, upgrading the application and its dependencies.
Mental Model
Think of PHP installations as several kitchens in the same building. Each kitchen has its own recipe book (php.ini) and ingredients (extensions).
You may have added Mcrypt to the recipe book used by the web-server kitchen, but php artisan migrate is cooking in the command-line kitchen. If that kitchen does not have Mcrypt available, Laravel cannot use it.
Before changing settings, first ask the terminal which kitchen it is using: which php executable, which php.ini, and which extensions are loaded.
Syntax and Examples
Use these commands from the Laravel project directory to inspect the PHP used by Artisan:
which php
php --version
php --ini
php -m | grep -i mcrypt
php --ri mcrypt
What each command does:
which phpshows the full path of the PHP executable found in your shellPATH.php --versionshows the PHP version.php --inilists the loaded configuration file and additional scanned.inifiles.php -mlists loaded modules. Thegrepcommand searches that list for Mcrypt.php --ri mcryptdisplays Mcrypt extension information when it is loaded.
A successful module check looks similar to this:
mcrypt
If php -m | grep -i mcrypt prints nothing, Mcrypt is not loaded for the CLI PHP that runs Artisan.
For an older, compatible PHP installation where the extension is available, an extension entry may look like this in the CLI-loaded configuration file:
extension=mcrypt
Step by Step Execution
Consider this terminal session:
$ which php
/usr/bin/php
$ php --ini
Configuration File (php.ini) Path: /etc
Loaded Configuration File: (none)
Scan for additional .ini files in: (none)
$ php -m | grep -i mcrypt
Step by step:
which phpshows that the shell is using/usr/bin/php.php --inireports Loaded Configuration File:(none). Therefore, PHP is not reading the configuration file you may have edited elsewhere.- The module search prints no output, so Mcrypt is not loaded for this CLI process.
- When you run the following command, Artisan uses exactly that CLI process:
php artisan migrate
- Laravel checks for Mcrypt, does not find it, and displays the error.
A useful comparison is checking the PHP executable that a web server reports through a temporary diagnostic script:
<?php
phpinfo();
The web page may show a different PHP version or a different Loaded Configuration File. That confirms the web server and terminal are using separate PHP environments. Remove diagnostic pages such as this after troubleshooting because phpinfo() exposes server configuration details.
Real World Use Cases
This same diagnostic process is useful beyond Mcrypt:
- Running Laravel jobs and queues: a queue worker launched in a terminal may use a different PHP binary from the web application.
- Missing extensions: errors involving
pdo_mysql,mbstring,curl,zip,intl, orgdoften come from the wrong PHP configuration being edited. - Deployment scripts: CI servers and cron jobs commonly run CLI PHP, so they need their own extension checks.
- Multiple PHP versions: a developer may run one PHP version for a legacy application and another for a modern application.
- Containerized applications: the local machine may have an extension installed, while the Docker PHP image does not.
Real Codebase Usage
In real projects, developers avoid discovering extension problems only after a framework crashes. Common practices include:
- Declare the requirement in Composer metadata when maintaining a package:
{
"require": {
"ext-mbstring": "*",
"ext-pdo": "*"
}
}
- Check the runtime used by scripts rather than assuming the default
phpcommand is correct:
/path/to/php artisan migrate --force
-
Use a reproducible environment such as a container, VM, or documented PHP version manager setup so every developer has the same extensions.
-
Upgrade legacy dependencies when possible. For Laravel 4 applications, an upgrade plan is safer than depending indefinitely on obsolete cryptographic extensions.
-
Keep configuration environment-specific. A web server restart may be needed after changing web PHP settings, but a CLI command starts a fresh process every time; it simply needs to read the right configuration and extension files.
Common Mistakes
Editing the wrong php.ini
A common mistake is changing a php.ini found by a web-server control panel, MAMP, or an online tutorial without checking what CLI PHP loads.
# Always inspect the PHP that Artisan will use.
php --ini
Avoid this by editing only the file identified as Loaded Configuration File for the relevant PHP executable.
Assuming an uncommented line means the extension loaded
This line alone does not prove Mcrypt is working:
extension=mcrypt
PHP may be unable to find the extension file, the directive may be in an unscanned file, or the extension may not be compatible with that PHP version. Verify with:
php -m | grep -i mcrypt
Checking only phpinfo() in a browser
phpinfo() describes the web-server PHP process, not necessarily the CLI process used by php artisan.
Avoid this by running CLI checks in the same terminal where you run migrations.
Installing an extension for the wrong PHP version
With multiple PHP versions, an extension built for one version may not load in another. Check both the binary and version first:
Comparisons
| Situation | What is being checked | Best diagnostic command |
|---|---|---|
php artisan migrate fails | CLI PHP extensions | php -m and php --ini |
| Browser page fails | Web-server PHP extensions | phpinfo() temporarily, then inspect server configuration |
php runs an unexpected version | Shell executable selection | which php and php --version |
| Extension is configured but absent | Whether PHP loaded it | php --ri extension_name |
| Approach |
|---|
Cheat Sheet
# Which PHP will `php artisan` use?
which php
php --version
# Which configuration file does that PHP load?
php --ini
# List loaded extensions
php -m
# Check one extension
php -m | grep -i mcrypt
php --ri mcrypt
# Run Artisan with a specific PHP binary
/path/to/php artisan migrate
php artisan ...uses CLI PHP.- The relevant configuration is the one reported by
php --ini. - No output from
php -m | grep -i mcryptmeans Mcrypt is not loaded. - Browser
phpinfo()output can describe a different PHP installation. - Mcrypt is legacy: it was deprecated in PHP 7.1 and removed from core PHP in PHP 7.2.
- Prefer upgrading old Laravel applications rather than building new work around Mcrypt.
FAQ
Why does Laravel say Mcrypt is missing when it appears enabled?
The enabled setting may belong to a different PHP installation or to web-server PHP. Artisan uses CLI PHP, so check php --ini and php -m in the terminal.
How do I find the PHP configuration used by Artisan?
Run php --ini in the same terminal session where you run php artisan migrate. Artisan uses that php executable unless you explicitly provide another path.
How can I verify that Mcrypt is loaded?
Run php -m | grep -i mcrypt. If it prints mcrypt, the CLI has loaded the extension. php --ri mcrypt provides additional details.
Do I need to restart PHP after changing php.ini?
For CLI commands, no server restart is needed because each command starts a new PHP process. For Apache or PHP-FPM, restart the relevant web service after changing its PHP configuration.
Can modern PHP use Mcrypt?
Mcrypt is no longer included in core PHP as of PHP 7.2. Legacy setups may have specific compatibility options, but modern applications should use supported framework and cryptography dependencies.
Should I remove Laravel's Mcrypt requirement from vendor code?
No. That only bypasses an environment check and can lead to failures or unsafe behavior later. Use a compatible environment temporarily or upgrade the application.
Why does disagree with ?
Mini Project
Description
Create a small shell-based environment audit for a legacy Laravel project. The audit reports which PHP executable is being used, which configuration files it loads, and whether Mcrypt is available before a migration is attempted.
Goal
Write a script that prevents a migration from running when the active CLI PHP does not have Mcrypt loaded.
Requirements
Requirement 1
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.