A Laravel application can stop on the error SQLSTATE[HY000]: General error: 1615 Prepared statement needs to be re-prepared, often when deleting or updating data. MySQL reports that a prepared statement must be prepared again, because the information it keeps in memory about a table changed between preparation and execution. This cache is shared by the whole server and cannot be enlarged for a single hosting account. The fix is therefore made in your application: tell PDO to emulate prepared statements on the PHP side.
In short: add the line PDO::ATTR_EMULATE_PREPARES => true, to the 'options' of the mysql block in config/database.php, then run php artisan config:cache if the configuration is cached. Do not use Pdo\Mysql:: before PHP 8.4.
Prerequisites
- Access to your Laravel application's files, by FTP or SSH.
- A MySQL database used with Laravel's
mysql driver.
Before you start
- Add a single line. Do not replace the whole
mysql block of your configuration with an example found online: you would lose your own settings.
- Write
PDO::ATTR_EMULATE_PREPARES, not Pdo\Mysql::ATTR_EMULATE_PREPARES. The Pdo\Mysql class only exists from PHP 8.4. On PHP 8.3 or earlier, the line causes a fatal error (Class "Pdo\Mysql" not found). PDO::ATTR_EMULATE_PREPARES works on every PHP version offered in the Apanel console.
- Protection against SQL injection stays active. With emulation, PDO escapes the values bound by Laravel itself (Eloquent, Query Builder,
? parameters). Keep the utf8mb4 character set of Laravel's default configuration.
- Do not add
ATTR_PERSISTENT. Persistent connections do not fix error 1615 and pile up on a shared server.
How do I fix error 1615?
- Open your application's
config/database.php file.
- In the
'mysql' => [ ... ] block, find the 'options' key.
- Add the line
PDO::ATTR_EMULATE_PREPARES => true, to the options array. With the configuration shipped by recent Laravel versions, the result looks like this:
'options' => extension_loaded('pdo_mysql') ? array_filter([
(PHP_VERSION_ID >= 80500 ? Mysql::ATTR_SSL_CA : PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'),
PDO::ATTR_EMULATE_PREPARES => true,
]) : [],
If your file has another form of 'options', add the same line to its array without touching the rest.
- Save the file and upload it to the server.
- If you cached the configuration, rebuild it over SSH, from the application folder:
php artisan config:cache
- Repeat the operation that caused the error.
Troubleshooting
| What you see |
What to do |
Class "Pdo\Mysql" not found |
The line uses Pdo\Mysql:: while the website runs PHP 8.3 or earlier. Replace Pdo\Mysql::ATTR_EMULATE_PREPARES with PDO::ATTR_EMULATE_PREPARES. |
| Error 1615 persists after the change |
The configuration is still cached: run php artisan config:cache (or php artisan config:clear) in the application folder. Also check that the line was added to the mysql block and not to another driver. |
| The error appears outside Laravel, in another PHP script |
The same setting exists for any code that uses PDO: $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); after connecting. |
Going further