Я пытался получить доступ к этой конкретной службе REST со страницы PHP, которую я создал на нашем сервере. Я сузил проблему до этих двух строк. Итак, моя страница PHP выглядит так:
<?php
$response = file_get_contents("https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json");
echo $response; ?>
Страница умирает в строке 2 со следующими ошибками:
- Предупреждение: file_get_contents (): операция SSL не выполнена с кодом 1.
Сообщения об ошибках OpenSSL: ошибка: 14090086: SSL
подпрограммы: SSL3_GET_SERVER_CERTIFICATE: сбой проверки сертификата в
… PHP в строке 2
- Предупреждение: file_get_contents (): не удалось включить шифрование в … php on
строка 2- Предупреждение:
file_get_contents (https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json
):
не удалось открыть поток: операция не удалась в … php в строке 2
Мы используем сервер Gentoo. Недавно мы обновились до версии PHP 5.6. Именно после обновления появилась эта проблема.
Я нашел, когда я заменяю REST-сервис с адресом вроде https://www.google.com
; моя страница работает просто отлично.
В более ранней попытке я установил “verify_peer”=>false
и передал это в качестве аргумента file_get_contents, как описано здесь: file_get_contents игнорируя verify_peer =>ложный? Но, как заметил писатель; это не имело никакого значения.
Я спросил одного из наших администраторов сервера, существуют ли эти строки в нашем файле php.ini:
Он сказал мне, что поскольку мы находимся на Gentoo, openssl компилируется при сборке; и это не установлено в файле php.ini.
Я также подтвердил, что allow_url_fopen
работает. В связи со спецификой этой проблемы; Я не нахожу много информации для помощи. Кто-нибудь из вас сталкивался с чем-то подобным? Благодарю.
Это была чрезвычайно полезная ссылка для поиска:
http://php.net/manual/en/migration56.openssl.php
Официальный документ, описывающий изменения, внесенные в open ssl в PHP 5.6
Отсюда я узнал еще об одном параметре, который я должен был установить в false: «verify_peer_name» => false
Итак, мой рабочий код выглядит так:
<?php
$arrContextOptions=array(
"ssl"=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
),
);
$response = file_get_contents("https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json", false, stream_context_create($arrContextOptions));
echo $response; ?>
Вы не должны просто отключить проверку. Скорее вы должны загрузить пакет сертификатов, возможно, локон расслоение подойдет?
Затем вам просто нужно поместить его на ваш веб-сервер, предоставив пользователю, который запускает php, разрешение на чтение файла. Тогда этот код должен работать для вас:
$arrContextOptions=array(
"ssl"=>array(
"cafile" => "/path/to/bundle/cacert.pem",
"verify_peer"=> true,
"verify_peer_name"=> true,
),
);
$response = file_get_contents("https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json", false, stream_context_create($arrContextOptions));
Надеюсь, корневой сертификат сайта, к которому вы пытаетесь получить доступ, находится в комплекте curl. Если это не так, это все равно не будет работать, пока вы не получите корневой сертификат сайта и не поместите его в файл сертификата.
Я исправил это, убедившись, что OpenSSL был установлен на моей машине, а затем добавил это в мой php.ini:
openssl.cafile=/usr/local/etc/openssl/cert.pem
Вы можете обойти эту проблему, написав пользовательскую функцию, которая использует curl, например:
function file_get_contents_curl( $url ) {
$ch = curl_init();
curl_setopt( $ch, CURLOPT_AUTOREFERER, TRUE );
curl_setopt( $ch, CURLOPT_HEADER, 0 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, TRUE );
$data = curl_exec( $ch );
curl_close( $ch );
return $data;
}
Тогда просто используйте file_get_contents_curl
вместо file_get_contents
всякий раз, когда вы вызываете URL, который начинается с https.
Если у вас версия PHP 5, попробуйте установить cURL, набрав в терминале следующую команду:
sudo apt-get install php5-curl
По сути, вы должны установить переменную среды SSL_CERT_FILE равной пути файла PEM ssl-сертификата, загруженного по следующей ссылке: http://curl.haxx.se/ca/cacert.pem.
Мне понадобилось много времени, чтобы понять это.
следующие шаги помогут решить эту проблему,
curl.cainfo
и вставьте абсолютный путь где у вас есть скачать сертификат. curl.cainfo ="C:\wamp\htdocs\cert\cacert.pem"
надеюсь, это поможет !!
Просто хотел добавить к этому, так как столкнулся с той же проблемой, и ничего, что я нигде не мог найти, работало бы (например, загрузка файла cacert.pem, настройка cafile в php.ini и т. Д.)
Если вы используете NGINX и ваш SSL-сертификат поставляется с «промежуточным сертификатом», вам нужно объединить промежуточный файл сертификата с вашим основным файлом «mydomain.com.crt», и он должен работать. Apache имеет настройку, специфичную для промежуточных сертификатов, но NGINX нет, поэтому он должен находиться в том же файле, что и ваш обычный сертификат.