В PHP при загрузке или обмене данными с другим сервером через защищённое соединение может возникнуть ошибка:
SSL certificate error: unable to get local issuer certificate
Ошибка означает, что на сервере не установлен SSL сертификат.
Чаще всего она наблюдается, когда мы ставим локальные платформы (сервера) быстрого развёртывания для веб-разработки, таких как WAMP, XAMPP и других.
Для решения проблемы нам необходимо установить SSL сертификат.
Сертификат, например, можно взять отсюда (чтобы самим не генерировать ;):
https://curl.haxx.se/docs/caextract.html
- Скачиваем сертификат помещаем в папку C:\wamp\cacert.pem
(у меня установлен WAMP, рекомендую) - Включаем в Apache mod_ssl.
- Добавляем расширение (ну или раскомментируем строчку) в файле php.ini:
extension=php_openssl.dll - Добавляем в php.ini также параметры:
curl.cainfo=»C:/wamp/cacert.pem»
openssl.cafile=»C:/wamp/cacert.pem»
Перезагружаем сервер. После чего ошибка должна быть решена.
Финальная проверка настройки
После подключения файла сертификатов перезапустите веб-сервер или PHP-FPM и выполните тестовый HTTPS-запрос из того же окружения, где возникала ошибка. Важно проверять не браузер, а именно PHP: CLI и веб-сервер могут использовать разные php.ini.
php --ini
php -i | grep -E "curl.cainfo|openssl.cafile"
php -r "var_dump(file_get_contents('https://example.com') !== false);"
Для cURL указывается curl.cainfo, для потоков OpenSSL — openssl.cafile. На Windows путь лучше писать полностью и без относительных директорий. Если используется не глобальный php.ini, а отдельная настройка клиента, можно передать CA bundle прямо в cURL:
curl_setopt($ch, CURLOPT_CAINFO, 'C:\php\extras\ssl\cacert.pem');
Не отключайте проверку SSL через CURLOPT_SSL_VERIFYPEER = false как постоянное решение. Это скрывает проблему и делает соединение уязвимым. Такая настройка допустима только для короткой диагностики в локальной среде, и после проверки её нужно вернуть обратно.
Если CA bundle указан верно, но ошибка осталась, проверьте цепочку сертификатов на стороне удалённого сервера. Иногда браузер открывает сайт, потому что умеет достраивать цепочку, а PHP/cURL получает неполную цепочку и честно падает. В таком случае исправлять нужно сертификаты сервера, а не PHP-код.
Правильный итог: актуальный cacert.pem, явно указанные curl.cainfo и openssl.cafile, перезапуск PHP и тест именно из того окружения, где работает приложение.