#Что означает ошибка
Uncaught PDOException — SQLSTATE[HY000] и ошибки подключения
Fatal error: Uncaught PDOException: SQLSTATE[HY000] — PHP не смог выполнить действие с базой данных. Код HY000 общий, поэтому смотреть нужно сообщение после него: [2002] Connection refused, [1045] Access denied, [1049] Unknown database, [1213] Deadlock, [HY000] database is locked (SQLite).
Каждый из текстов указывает на свою причину и решается по-разному.
PDOException возникает при ошибке подключения или запроса. Проверьте DSN, логин/пароль, доступность БД и текст ошибки.
#Причины и решения
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Неверные данныеDSN. | Ошибка. | Проверьте. |
| БД недоступнаСервер. | Нет подключения. | Запустите. |
| Ошибка SQLЗапрос. | Синтаксис. | Исправьте. |
| Нет расширенияpdo_mysql. | Драйвер. | Включите. |
#Пошаговое решение
- Прочитайте полный текст ошибкиВ журнале PHP найдите полный текст исключения
PDOExceptionи код послеSQLSTATE, напримерHY000 [2002],[1045]или[2006]. Ошибки означают соответственно недоступный сервер, отказ авторизации или потерянное соединение — их нельзя исправлять одной настройкой. Сохраните сообщение без опубликования пароля подключения. - Проверьте доступность СУБДЕсли ошибка указывает на отсутствие соединения, администратор сервера проверяет
systemctl status mysql/mariadb, затем имя хоста и порт базы черезss -ltnp. Для удалённой БД отдельно проверьте DNS и сетевую доступность только разрешённого адреса. Не открывайте порт 3306 всем в Интернете. - Проверьте параметры подключенияВ конфигурации приложения проверьте DSN PDO,
host,portлибоunix_socket, имя БД и пользователя. Подключение кlocalhostв MySQL может использовать UNIX-сокет, а к127.0.0.1— TCP; выбирайте вариант, который реально настроен. Не выводите содержимое.envили пароли в браузер. - Подключитесь из консолиПод той же учётной записью БД из терминала сервера выполните безопасную команду
mysql -h фактический_хост -u фактический_пользователь -p -e "SELECT 1", указав значения из защищённой конфигурации. Если здесь тоже отказ 1045, проверяйте права/пароль; если консоль работает, а PHP нет — проверьте драйверpdo_mysqlименно веб-версии PHP. - Включите логирование исключенийВ коде используйте перехват
PDOException, пишите в закрытый серверный журнал сообщение и контекст запроса без паролей и личных данных; пользователю показывайте нейтральную ошибку. После устранения причины выполните тестовый запрос и убедитесь, что проблема не повторяется в приложении и журнале базы.
#Ошибки подключения
2002 Connection refused / No such file — MySQL не запущен или неверный хост: проверьте systemctl status mysql, порт 3306 и параметр host (для сокета localhost, для TCP 127.0.0.1). 1045 Access denied — неверный логин/пароль или у пользователя нет прав на хост: GRANT ALL ON база.* TO 'user'@'localhost' IDENTIFIED BY 'пароль'; FLUSH PRIVILEGES;. 1049 Unknown database — база не создана.
#Ошибки запросов
1146 Table doesn't exist — не применены миграции или неверный префикс таблиц. 1054 Unknown column — расхождение схемы. 1062 Duplicate entry — нарушение уникального ключа. 2006 MySQL server has gone away — тайм-аут или слишком большой пакет: увеличьте max_allowed_packet. Для SQLite database is locked — другой процесс держит блокировку; включите PRAGMA busy_timeout=5000 и режим WAL.
#Отладка
Включите режим исключений: new PDO($dsn,$u,$p,[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]) и обработайте try { ... } catch (PDOException $e) { error_log($e->getMessage()); }. Не выводите сообщение пользователю: оно раскрывает пароли и структуру БД. Проверьте расширение: php -m | grep -i pdo и наличие pdo_mysql, pdo_sqlite.
#Проверка из консоли
Проверьте подключение вне PHP: mysql -h 127.0.0.1 -u user -p имя_базы. Если из консоли не подключается, проблема не в коде. Посмотрите журнал MySQL /var/log/mysql/error.log и journalctl -u mysql -n 50.
systemctl status mysqlmysql -h 127.0.0.1 -u user -p -e "SELECT 1"php -m | grep -i pdo