# Broken pdo\_mysql in php 8.3

**URL:** <https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379>\
**Category:** PHP Installation and Configuration\
**Created:** [January 23, 2025, 1:35am UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379 "2025-01-23T01:35:11Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![mcg](https://www.phphelp.com/user_avatar/www.phphelp.com/mcg/32/4099_2.png) [@mcg](https://www.phphelp.com/u/mcg)\
**Post date:** [January 23, 2025, 1:35am UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/1 "2025-01-23T01:35:11Z")

</div>

I’ve looked in vain for a definitive answer to this, but there doesn’t seem to be one. I’ve installed a LAMP stack on a fresh build of xubuntu 24.04 with php8.3 which I use mostly from a shell. phpinfo() claims that pdo\_mysql is loaded:

> PDO
> 
> PDO support =\> enabled  
> PDO drivers =\> mysql
> 
> pdo\_mysql
> 
> PDO Driver for MySQL =\> enabled  
> Client API version =\> mysqlnd 8.3.6
> 
> Directive =\> Local Value =\> Master Value  
> pdo\_mysql.default\_socket =\> /var/run/mysqld/mysqld.sock =\> /var/run/mysqld/mysqld.sock

but -\>prepare() statements fail. Trying to load the extension from php.ini results in

> PHP Warning: PHP Startup: Unable to load dynamic library ‘pdo\_mysql’ (tried: /usr/lib/php/20230831/pdo\_mysql

despite the fact that ls shows the file **is** there in both cases. Anybody know what gives?

---

<div class="post-metadata">

**Author:** ![ErnieAlex](https://www.phphelp.com/letter_avatar_proxy/v4/letter/e/bc8723/32.png) [@ErnieAlex](https://www.phphelp.com/u/ErnieAlex)\
**Post date:** [January 24, 2025, 6:31pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/2 "2025-01-24T18:31:20Z")

</div>

Well, I looked that error up and some other people have solved it with these commands below.  
But, you should make a backup of your PHP system before you run them in case it causes issues.  
( Better safe than sorry!) I think the issue is something to do with the library address. Yours is /usr/lib/php/20230831/pdo\_mysql and it might not be linked to correctly in the PHP system.

First, you might want to just reinstall it using this command:  
`sudo apt-get install php8.3-mysql`  
If does not work, try these after backing up your PHP system.  
`sudo apt-get --purge remove php-common`  
`sudo apt-get install php-common php-mysql php-cli`

Here is the location of the page I got this info from in case you want to read further before trying these.  
[Stack Overflow PDO load error](https://stackoverflow.com/questions/62240102/php-warning-php-startup-unable-to-load-dynamic-library-pdo-mysql-so)

---

<div class="post-metadata">

**Author:** ![mcg](https://www.phphelp.com/user_avatar/www.phphelp.com/mcg/32/4099_2.png) [@mcg](https://www.phphelp.com/u/mcg)\
**Post date:** [January 24, 2025, 7:21pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/3 "2025-01-24T19:21:02Z")

</div>

Thanks Ernie, I saw that page and tried everything that was suggested (purge & re-install, --forece-reinstall), but still no dice. I’m no linux expert but the files are properly linked and in the right places as far as I can tell. I think I’ve determined that the fault is with pdo, not just pdo\_mysql.

This has happened before, so all my scripts are safely backed up. I’ll install lamp stacks on some other machines I have about and see what I can see. Annoying though.

---

<div class="post-metadata">

**Author:** ![ErnieAlex](https://www.phphelp.com/letter_avatar_proxy/v4/letter/e/bc8723/32.png) [@ErnieAlex](https://www.phphelp.com/u/ErnieAlex)\
**Post date:** [January 24, 2025, 7:39pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/4 "2025-01-24T19:39:13Z")

</div>

I understand Annoying! Ha! Been there so many times.

They keep saying to just use: `sudo apt install php-pdo` so install PDO on PHP in Lamp.  
Did you use a full install package or do it piece by piece?  
I read awhile ago how to install of it and reread it. Here is a link you might get something out of.  
I have one Ubuntu system somewhere here, a small pi system if I remember correctly.  
Maybe I could try it this weekend and see how it goes. Here is that link I was reading  
on the install procedures. Not sure if it will help, but, maybe… [Lamp-Ubunto-Php-PDO-install](https://www.digitalocean.com/community/tutorials/how-to-install-lamp-stack-on-ubuntu)  
Good luck, leaving for several hours. Will check back when I get back!

---

<div class="post-metadata">

**Author:** ![mcg](https://www.phphelp.com/user_avatar/www.phphelp.com/mcg/32/4099_2.png) [@mcg](https://www.phphelp.com/u/mcg)\
**Post date:** [January 24, 2025, 7:41pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/5 "2025-01-24T19:41:22Z")

</div>

Tks, that’s actually the page I typically use. I’ve tried the re-install php-pdo, but I’ll give it another whirl.

---

<div class="post-metadata">

**Author:** ![phdr](https://www.phphelp.com/letter_avatar_proxy/v4/letter/p/91b2a8/32.png) [@phdr](https://www.phphelp.com/u/phdr)\
**Post date:** [January 24, 2025, 11:48pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/6 "2025-01-24T23:48:34Z")

</div>

How are you invoking/requesting the script with the phpinfo() statement and how are you invoking/requesting the script that fails?

How do you know that -\>prepare() statements fail? What symptom or error do you get and do you have and have confirmed via a phpinfo() statement that php’s error\_reporting set to E\_ALL (it should always be this value) and display\_errors set to ON so that all php errors get reported and displayed?

What is your database specific code, starting with the connection through to the code that fails, less any connection credentials?

---

<div class="post-metadata">

**Author:** ![mcg](https://www.phphelp.com/user_avatar/www.phphelp.com/mcg/32/4099_2.png) [@mcg](https://www.phphelp.com/u/mcg)\
**Post date:** [January 25, 2025, 5:50pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/7 "2025-01-25T17:50:19Z")

</div>

phdr:

`PHP Fatal error: Uncaught Error: Call to undefined method PDOException::prepare() in /home/mar...`

which results when calling

```auto
	function fn_chart_read(string $category) : array	{
		$dbh = fn_db_connect();
		try	{
			$s = $dbh->prepare("CALL accounts.p_chart_read(?)");
			$s->bindParam(1, $category);
			$s->execute();
			return $s->fetchAll(PDO::FETCH_ASSOC);
		}
		catch (PDOException $err)	{
			return false;
		}
	}

```

All errors are on:

```auto
ini_set('display_errors', 1);
error_reporting(E_ALL);

```

and as shown above, phpinfo() says pdo\_mysql is loaded for both cli and apache.

The process is initiated from the cli:

`chart list x`  
using  
`alias chart='php chart.php'`

```auto
$command = $argv[1] ?? NULL;
	switch ($command)	{
...
		case "list" : // list [{"category"}]
			$operand = strtoupper($argv[2] ?? "X");
			switch (true)	{
				case !in_array($operand, ["A", "L", "Q", "R", "E", "X"]) :
					die(RED . "Invalid operand.\n" . WHT);
					break;
				default :
					fn_chart_display(fn_chart_read($operand));
					die();
					break;
			}
			break;

```

Having had trouble with other memory-hogging software, I built another machine with 32GB, as above, with xubuntu 24.04. The scripts worked without issue on the older 16GB machine (and still do!), so I don’t believe they are the issue.  
Tks.

```auto

```

---

<div class="post-metadata">

**Author:** ![phdr](https://www.phphelp.com/letter_avatar_proxy/v4/letter/p/91b2a8/32.png) [@phdr](https://www.phphelp.com/u/phdr)\
**Post date:** [January 25, 2025, 6:09pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/8 "2025-01-25T18:09:15Z")

</div>

The error means that $dbh is an instance of the PDOException class. The fn\_db\_connect() is somehow returning an instance of this class, not a connection.

---

<div class="post-metadata">

**Author:** ![mcg](https://www.phphelp.com/user_avatar/www.phphelp.com/mcg/32/4099_2.png) [@mcg](https://www.phphelp.com/u/mcg)\
**Post date:** [January 25, 2025, 6:21pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/9 "2025-01-25T18:21:28Z")

</div>

Sorry, I’m not clear on what you mean:

```auto
	function fn_db_connect()	{ // get database handle
		try	{
			return new PDO("mysql:host=yadayadayada", "dev", "dev");
		}
		catch (PDOException $err)	{
			return $err;
		}
	}

```

which works flawlessly on the prior machine. There’s no failure until the `prepare()` statement.

The scripts were designed to be stateless so I can use them to drive a REST api (whenever I get around to that).

The more I think about this, the more I think it’s an issue with the ubuntu installer not flipping switches properly. Is there a more trustworthy ppa on, say, github or [php.net](http://php.net)?

---

<div class="post-metadata">

**Author:** ![phdr](https://www.phphelp.com/letter_avatar_proxy/v4/letter/p/91b2a8/32.png) [@phdr](https://www.phphelp.com/u/phdr)\
**Post date:** [January 25, 2025, 6:36pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/10 "2025-01-25T18:36:28Z")

</div>

You are returning the connection error, which is an instance of the PDOException class.

The only database exceptions you should catch and handle in your code are for user recoverable errors, such as when inserting/updating duplicate user submitted data. For all other query errors and all other type of queries and the connection, you should do nothing in your code and let php handle any database exception in these cases. Once you remove the try/catch for the connection logic, php will report and display the actual reason for the connection failure, via an uncaught exception error. By handling this in your code and NOT testing the return value from the connection call before using it, you are just getting a follow-on error having nothing to do with the actual problem.

Also, when you make the connection, you should -

1. Set the character set to match your database tables, so that no character conversion occurs over the connection.
2. Set the emulated prepared query setting to false, you want to run real prepared queries whenever possible.
3. Set the default fetch mode to assoc, so that you don’t need to specify it in each fetch statement.
4. If you are calling the connection function multiple times in any script, you need to make the connection a static variable inside the function and only make a new connection if there isn’t already one.

---

<div class="post-metadata">

**Author:** ![mcg](https://www.phphelp.com/user_avatar/www.phphelp.com/mcg/32/4099_2.png) [@mcg](https://www.phphelp.com/u/mcg)\
**Post date:** [January 25, 2025, 7:09pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/11 "2025-01-25T19:09:08Z")

</div>

Thanks. I still don’t understand how that explains why it works on one machine and not the other. I’ll fire up the old machine and try returning a boolean on it and on this machine for the connection to see if it is indeed the issue.

Everything is set to utf-8, since I handle various languages. Since the ultimate aim is a stateless api, there’s no point in popping open a database handle until it’s actually needed and there are no logic errors in the cli request - hence the die() once we’re done. As for default fetch mode, the system is expected to be db agnostic, so some sql queries are returning explicit integer values to avoid problems with different dbms persuasions. Hence for example, this:

```auto
	function fn_account_create(array $data) : bool	{
		$dbh = fn_db_connect();
		try	{
			$s = $dbh->prepare("CALL accounts.p_ac_create(?, ?, ?, ?, ?, ?)");
			$s->bindParam(1, $data["account"]);
			$s->bindParam(2, $data["category"]);
			$s->bindParam(3, $data["title"]);
			$s->bindParam(4, $data["description"]);
			$s->bindParam(5, $data["sigma"]);
			$s->bindParam(6, $data["postable"]);
			$s->execute();
			return $s->fetch(PDO::FETCH_NUM)[0] == 1;
		}
		catch (PDOException $err)	{
			return false;
		}
	}

```

The catch clause is eventually meant to write the error to a log, not the user.

Turning off prepared query emulation is a good idea. I’ll let you know how I make out with things: I’m on salad duty, so I’m back and forth. 🙂  
Tks  
M

---

<div class="post-metadata">

**Author:** ![phdr](https://www.phphelp.com/letter_avatar_proxy/v4/letter/p/91b2a8/32.png) [@phdr](https://www.phphelp.com/u/phdr)\
**Post date:** [January 25, 2025, 7:25pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/12 "2025-01-25T19:25:13Z")

</div>

You can always specify the fetch mode in a fetch statement if you want to use a mode different from the default.

> [@mcg](#):
>
> The catch clause is eventually meant to write the error to a log, not the user.

If you do what I wrote, the uncaught exception will AUTOMATICALLY get displayed or logged, the same as php errors, based on php’s error\_reporting, display\_errors, and log\_errors settings. No code is required.

---

<div class="post-metadata">

**Author:** ![mcg](https://www.phphelp.com/user_avatar/www.phphelp.com/mcg/32/4099_2.png) [@mcg](https://www.phphelp.com/u/mcg)\
**Post date:** [January 25, 2025, 7:29pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/13 "2025-01-25T19:29:01Z")

</div>

I’ll give it a whirl.

---

<div class="post-metadata">

**Author:** ![reddig.hamburg](https://www.phphelp.com/user_avatar/www.phphelp.com/reddig.hamburg/32/4389_2.png) [@reddig.hamburg](https://www.phphelp.com/u/reddig.hamburg)\
**Post date:** [April 8, 2025, 12:17pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/14 "2025-04-08T12:17:53Z")

</div>

Guys, this isn’t about the code at all but failing to load the extension.  
So the error from the very first post was already the correct one to look at.

There are multiple reasons why this can fail.

- it is a wrong version of the file potentially compiled for a different architecture (32 bit vs. 64 bit , amd64 vs arm)  
=\> This can be fixed by installing the correct version

- the file actually is named pdo\_mysql.so and the config is not auto-appending the .so extension  
=\> This can be fixed by adjusting the configfile

- there is a dependecy (another library used by the pfo\_mysql extension) missing like i.e. the general mysql client libraries  
=\> This can be fixed by installing the missing library

- the loading order of the extensions is wrong  
=\> This can be fixed by changing the config

- you have more than one concurrent version of php installed and the “wrong” (older?) one is called  
=\> this can be fixed by adjusting the search path or uninstalling the concurrent version

- you are running the php with a non privileged user which isn’t allowed to read the extensions  
=\> this can be fixed by changing the file permissions

…  
you should therefore test with less complicated code called from the CLI

As a first step just running  
php -v  
from the cli

This should print the version information best case without errors, but I would expect the “extension” error to show

---

<div class="post-metadata">

**Author:** ![mcg](https://www.phphelp.com/user_avatar/www.phphelp.com/mcg/32/4099_2.png) [@mcg](https://www.phphelp.com/u/mcg)\
**Post date:** [April 8, 2025, 2:07pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/15 "2025-04-08T14:07:01Z")

</div>

This has been my suspicion all along. It has just happened again, a result, I expect, of keeping my little lab machines updated regularly. Code that has worked without issue for months all of sudden shows up with the same old error. I’ve tried all of your suggestions - uninstall/reinstall, purge/reinstall, change file permissions, re-install libraries (that are already there), check for more than one version (only 8.3.19 is there), rebuild machines and start with a fresh install, mess with config files. Maybe the php gods are angry with me. I’m at the point where I’m either going to stop updating machines (not) or just give up on php in favour of something else. One machine is a nuisance, 5 or 6 is a pain in the ass. 🙂

---

<div class="post-metadata">

**Author:** ![phdr](https://www.phphelp.com/letter_avatar_proxy/v4/letter/p/91b2a8/32.png) [@phdr](https://www.phphelp.com/u/phdr)\
**Post date:** [April 8, 2025, 4:14pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/16 "2025-04-08T16:14:04Z")

</div>

This started with a complaint about -\>prepare() statements failing. The database dependent code SHOULD have never reached the point of a prepare() statement if the connection failed.

Once the actual error and connection code was posted, the symptom of -\>prepare() statements failing turned out to be connection code catching and returning the PDOException object, where it was (unconditionally) treated as through it was a PDO object, producing a follow-on error, instead of halting code execution and displaying/logging the actual reason for the connection failure.

@mcg, once you followed the recommendations and changed the connection code to NOT catch and (miss) handle a connection exception, what actual connection error did (are) you getting?

---

<div class="post-metadata">

**Author:** ![mcg](https://www.phphelp.com/user_avatar/www.phphelp.com/mcg/32/4099_2.png) [@mcg](https://www.phphelp.com/u/mcg)\
**Post date:** [April 8, 2025, 4:29pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/17 "2025-04-08T16:29:12Z")

</div>

As it happens, precisely the same error as above. As I’ve said repeatedly, the code works and has worked for months on end with no alterations. In fact, it still _does_ work as-is on a different machine. What the code _should_ have done is, IMHO amateur opinion, irrelevant. In any event, I appreciate your advice on good coding habits.

---

<div class="post-metadata">

**Author:** ![phdr](https://www.phphelp.com/letter_avatar_proxy/v4/letter/p/91b2a8/32.png) [@phdr](https://www.phphelp.com/u/phdr)\
**Post date:** [April 8, 2025, 4:43pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/18 "2025-04-08T16:43:50Z")

</div>

If the error is this -

> [@mcg](#):
>
> PHP Fatal error: Uncaught Error: Call to undefined method PDOException::prepare()

It means that the connection is failing for some reason. The error handling for a connection error (which apparently reverted back to returning the PDO **Exception** object) is hiding whatever error information there is and because it is not halting execution, is producing a bogus follow-on error at the -\>prepare() statement.

If you simply remove all the try/catch logic in the connection function, as was already stated -

> [@phdr](#):
>
> the uncaught exception will AUTOMATICALLY get displayed or logged, the same as php errors, based on php’s error\_reporting, display\_errors, and log\_errors settings. No code is required.

---

<div class="post-metadata">

**Author:** ![reddig.hamburg](https://www.phphelp.com/user_avatar/www.phphelp.com/reddig.hamburg/32/4389_2.png) [@reddig.hamburg](https://www.phphelp.com/u/reddig.hamburg)\
**Post date:** [April 9, 2025, 11:30am UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/19 "2025-04-09T11:30:40Z")

</div>

Which operating system are you using and how have you installed php on those boxes?

Actually this is the first time I hear about such a “stubborn” extension, specially when it’s kind of a standard one like PDO.

Please be as well aware that there are zts and none-zts versions existing which may be incompatible with each others extension.

Please post your full install commands for review.

Also please check  
php -v  
output on the working machine

This is a bit of looking into a black hole somehow.  
It should work “out of the box” on a fresh install.  
Still there can be things impacting the installation like pulling from a broken repository or so.

It’s hard to debug remotely

Edit:  
Just seen that you are running xubuntu 24.04  
I haven’t have huge experience with that one as I usually use debian machines, but still it should just work.  
Regardless, package names might be slightly different per each distro.

---

<div class="post-metadata">

**Author:** ![mcg](https://www.phphelp.com/user_avatar/www.phphelp.com/mcg/32/4099_2.png) [@mcg](https://www.phphelp.com/u/mcg)\
**Post date:** [April 9, 2025, 7:03pm UTC](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379/20 "2025-04-09T19:03:33Z")

</div>

I’ve just rebuilt one of the offenders (same xubuntu 24.04 server on a rpi 4b), this time skipping the apache install: my earlier project to build an API has gone up in smoke (too much work, other more interesting projects I have my eye on).  
So the install was this, following a fresh OS install & full update/upgrade:  
`sudo apt install mariadb-server mariadb-client`  
followed, after securing the db, with  
`sudo apt install php8.3-cli php8.3-common`  
and everything magically works again.  
On another machine,  
`$dbh = new PDO("mysql:server=127.0.0.1;dbname=gutenberg", "yada", "yada");`  
results in

```auto
PHP Fatal error: Uncaught PDOException: SQLSTATE[HY000] [2002] No such file or directory in /home/mcg/indexes.php:3
Stack trace:
#0 /home/marcel/indexes.php(3): PDO->__construct()

```

the cause of which is obvious. (Don’t yell at me about the code: it was a quick and dirty script to populate a database, and it ran successfully unaltered on another machine.)  
At the risk of being monotonous, I think I need to point out again:  
phdr: I followed your advice, same problem: PDO issue.  
phdr/reddig: _The code has not changed._ This seems to just happen out of the blue: I’m religious about making sure all machines are updated and singing from the same songbook. No new software is ever installed, they’re just plain-jane LAMP servers. One day it works, next day the PDO issue. Version checking always shows php 8.3. Go look for the socket file, sometimes it’s there, sometimes it isn’t. Where would it go? It’s inexplicable and makes me question my sanity. More than usual.

P.S. The long-and-short of it is this: all of my messing around tells me this is an os/apt/file issue, not a problem with the php install itself. How to resolve it? No idea. I’ll keep an eye on the newest installs and watch for it to happen again.

[Next page](https://www.phphelp.com/t/broken-pdo-mysql-in-php-8-3/36379.md?page=2)
