What's Actually Happening
MySQL is running. PHP is installed. Your connection string looks fine. Then your script fires and you get this:
Warning: mysqli_connect(): (HY000/2002): No such file or directory
The "file or directory" PHP can't find isn't your PHP script or your config. It's a Unix socket file โ the communication channel MySQL uses when you connect via localhost.
One thing trips people up here: passing localhost to mysqli_connect() doesn't use TCP/IP. PHP skips the network stack entirely and looks for a Unix domain socket on the filesystem. If PHP expects the socket at /tmp/mysql.sock but MySQL put it at /var/run/mysqld/mysqld.sock, you get this error every time.
Debug: Find Where the Socket Actually Is
Start by confirming MySQL is running:
sudo systemctl status mysql
# or for MariaDB:
sudo systemctl status mariadb
Not running? Start it and you're done. Still running? The socket path mismatch is your culprit. Find the real socket location:
mysql -u root -p -e "SHOW VARIABLES LIKE 'socket';"
Example output:
+---------------+--------------------------+
| Variable_name | Value |
+---------------+--------------------------+
| socket | /var/run/mysqld/mysqld.sock |
+---------------+--------------------------+
Now check what PHP thinks the socket path should be:
php -r "echo ini_get('mysqli.default_socket');"
Or search directly in php.ini:
grep -r "mysqli.default_socket" /etc/php/
Different paths? That's your problem. Same paths but the socket file doesn't exist on disk? MySQL isn't running, or it crashed on startup.
Solution 1: Use 127.0.0.1 Instead of localhost (Quickest Fix)
Swap localhost for 127.0.0.1. No config changes, no restarts โ just one character difference that completely changes how PHP connects:
<?php
// Before (uses Unix socket โ breaks if socket path is wrong)
$conn = mysqli_connect('localhost', 'myuser', 'mypass', 'mydb');
// After (forces TCP/IP โ bypasses the socket issue entirely)
$conn = mysqli_connect('127.0.0.1', 'myuser', 'mypass', 'mydb');
?>
With 127.0.0.1, PHP connects over TCP on port 3306. MySQL listens there by default, so this works immediately on most setups.
Using PDO? Same swap:
<?php
$pdo = new PDO('mysql:host=127.0.0.1;port=3306;dbname=mydb', 'myuser', 'mypass');
?>
Solution 2: Fix the Socket Path in php.ini (Proper Fix)
If you can't change the connection code โ say, it's a legacy app or a CMS you don't control โ align PHP's socket setting with where MySQL actually put it.
First, find your active php.ini:
php --ini | grep "Loaded Configuration"
Open that file and update all three socket settings to match the path from SHOW VARIABLES LIKE 'socket':
; In php.ini
mysqli.default_socket = /var/run/mysqld/mysqld.sock
pdo_mysql.default_socket = /var/run/mysqld/mysqld.sock
mysql.default_socket = /var/run/mysqld/mysqld.sock
Then restart your PHP process:
# For PHP-FPM:
sudo systemctl restart php8.1-fpm
# For Apache with mod_php:
sudo systemctl restart apache2
Solution 3: Pass the Socket Explicitly in Your Code
Rather than relying on php.ini defaults, hardcode the socket path directly in mysqli_connect(). Useful when you need one connection to use a socket and others to use TCP:
<?php
$conn = mysqli_connect(
'localhost',
'myuser',
'mypass',
'mydb',
3306,
'/var/run/mysqld/mysqld.sock' // explicit socket path
);
?>
OOP style:
<?php
$mysqli = new mysqli();
$mysqli->real_connect(
'localhost',
'myuser',
'mypass',
'mydb',
3306,
'/var/run/mysqld/mysqld.sock'
);
?>
Common Socket Paths by System
Socket locations vary by distro and MySQL variant. Here's where to look:
- Ubuntu/Debian (MySQL):
/var/run/mysqld/mysqld.sock - CentOS/RHEL (MySQL):
/var/lib/mysql/mysql.sock - MariaDB (most distros):
/var/run/mysqld/mysqld.sockor/tmp/mysql.sock - MAMP/XAMPP (macOS):
/Applications/MAMP/tmp/mysql/mysql.sock - Homebrew MySQL (macOS):
/tmp/mysql.sock
When in doubt, run SHOW VARIABLES LIKE 'socket' โ MySQL always knows where it put the file.
Verify the Fix
Test from the command line before touching your app:
php -r "
\$conn = mysqli_connect('127.0.0.1', 'myuser', 'mypass', 'mydb');
if (\$conn) {
echo 'Connected successfully\n';
mysqli_close(\$conn);
} else {
echo 'Error: ' . mysqli_connect_error() . '\n';
}
"
Or drop this temporary block into your app to see the server version on success:
<?php
$conn = mysqli_connect('127.0.0.1', 'myuser', 'mypass', 'mydb');
if (!$conn) {
die('Connection failed: ' . mysqli_connect_error());
}
echo 'Connected. MySQL server version: ' . mysqli_get_server_info($conn);
mysqli_close($conn);
?>
Key Takeaways
localhostand127.0.0.1are not interchangeable in PHP database connections. One hits a Unix socket file; the other goes over TCP/IP.- "No such file or directory" is a filesystem error, not a network error. PHP literally can't find the socket file at the path it expects.
- Switching between MySQL and MariaDB, or moving between distros, often changes the socket path. Always recheck.
- In Docker containers or mixed environments where socket paths shift,
127.0.0.1is the more portable choice โ it doesn't depend on any file existing on disk.

