Як змусити file_get_contents () працювати з HTTPS?


106

Я працюю над налаштуванням обробки кредитної картки, і мені потрібно було вирішити метод CURL. Наступний код справно працював, коли я використовував тестовий сервер (який не викликав URL-адресу SSL), але тепер, коли я тестую його на робочому сервері з HTTPS, він не вдається з повідомленням про помилку "не вдалося відкрити потік".

function send($packet, $url) {
  $ctx = stream_context_create(
    array(
      'http'=>array(
        'header'=>"Content-type: application/x-www-form-urlencoded",
        'method'=>'POST',
        'content'=>$packet
      )
    )
  );
  return file_get_contents($url, 0, $ctx);
}

Відповіді:


89

Спробуйте виконати наступний скрипт, щоб побачити, чи доступна обгортка https для ваших скриптів php.

$w = stream_get_wrappers();
echo 'openssl: ',  extension_loaded  ('openssl') ? 'yes':'no', "\n";
echo 'http wrapper: ', in_array('http', $w) ? 'yes':'no', "\n";
echo 'https wrapper: ', in_array('https', $w) ? 'yes':'no', "\n";
echo 'wrappers: ', var_export($w);

вихід повинен бути чимось на кшталт

openssl: yes
http wrapper: yes
https wrapper: yes
wrappers: array(11) {
  [...]
}

@volker Ось чому я попросив дозволити_url_fopen
Гордон

Що ж дивно, це те, що він каже, що openssl вимкнено, але згідно з phpinfo () він складається з ним, якщо я не бачу це неправильно.
Джеймс Сімпсон

phpinfo () повідомляє про це у рядку конфігурації чи є цілий розділ під назвою "OpenSSL"?
VolkerK

Гаразд, це просто в рядку конфігурації, а не розділ для нього. Я гадаю, що це проблема?
Джеймс Сімпсон

У мене все це є, і це все ще не працює. І дозволити_url_fopen. Тільки URL-адреси, які не є https, працюють із localhost.
Кертіс

116

Щоб дозволити обгортку https:

  • php_opensslрозширення повинно існувати і бути включено
  • allow_url_fopen повинні бути встановлені на on

У файл php.ini слід додати ці рядки, якщо таких немає:

extension=php_openssl.dll

allow_url_fopen = On

У моїй установці обоє встановлено "Увімкнено", але я все одно отримую помилку SSL "Попередження: file_get_contents (): SSL:
Час

53

Спробуйте наступне.

function getSslPage($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_REFERER, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

Примітка. Це вимикає перевірку SSL, тобто безпека, пропонована HTTPS, втрачається . Використовуйте цей код лише для тестування / локальної розробки, ніколи в Інтернеті чи інших мережах, що стоять перед громадськістю. Якщо цей код працює, це означає, що сертифікату SSL не довіряти або його неможливо перевірити, що слід розглядати як виправлення як окрему проблему.


29
Чому б ви відключили перевірку ssl при роботі з обробкою кредитних карт?
Петро

Дякую, хитрість тут: curl_setopt ($ ch, CURLOPT_SSL_VERIFYPEER, FALSE);
Ділан Б

46
$url= 'https://example.com';

$arrContextOptions=array(
      "ssl"=>array(
            "verify_peer"=>false,
            "verify_peer_name"=>false,
        ),
    );  

$response = file_get_contents($url, false, stream_context_create($arrContextOptions));

Це дозволить отримати вміст із URL-адреси, будь то HTTPS


Дякую! Це спрацювало на моєму кінці. Намагалися зателефонувати в FB Open Graph API :)
декодуванняпанда

Я намагався отримати доступ до мого домену з недійсним сертифікатом лише для тестових цілей, і хоча це відключає перевірку SSL, мені це було потрібно.
carla

Чудово! Я вже 5 днів намагаюся завантажити календар airbnb на своєму тестовому сайті XAMPP за допомогою file_get_contents, це вирішило проблему, дякую.
JohnnyBeGood

Мені працювали, намагаючись підключитися до тестового вікна Vagrant без дійсного сертифіката HTTP через https. Посилання на параметри контексту PHP SSL встановлюються тут: php.net/manual/en/context.ssl.php ; verify peer = Потрібна перевірка використаного сертифіката SSL; verify_peer_name = Потрібна перевірка імені одноранків.
Ентоні

Це не зламане сертифікат SSL і це отвір у безпеці?
webchun

10

Можливо, це пов’язано з тим, що ваш цільовий сервер не має дійсного сертифіката SSL.


Сервер, що запитує, не повинен мати сертифікат SSL.
ceejayoz

15
Я не сказав сервер, що запитує, я сказав цільовий сервер.
Еміль Вікстрьом

2
Це навчить мене скупитися. Хе! Прийміть мої вибачення та заяву.
ceejayoz

Цільовий сервер має дійсний сервер SSL.
Джеймс Сімпсон

@James, ви отримуєте помилку, якщо ви намагаєтесь встановити з'єднання з cURL? Або це абсолютно неможливо спробувати?
Еміль Вікстрьом

6

Просто додайте два рядки у файл php.ini.

extension=php_openssl.dll

allow_url_include = On

це працює для мене.


1
Ви, напевно, маєте на увазі, allow_url_fopenоскільки питання стосується відкриття URL-адреси, не враховуючи.
shukshin.ivan

5

У мене була така ж помилка. Установка allow_url_include = Onв php.iniфіксованою для мене.


5

HTTPS підтримується, починаючи з PHP 4.3.0, якщо ви склали для підтримки OpenSSL. Також переконайтеся, що цільовий сервер має дійсний сертифікат, брандмауер дозволяє вихідні з'єднання, а allow_url_fopenв php.ini встановлено значення true.


У мене PHP 5.2.8 з підтримкою OpenSSL. Я отримую таку ж помилку з цим, і цільовий сервер має дійсний сертифікат.
Джеймс Сімпсон

2
чи налаштований брандмауер, щоб дозволити вихідні https-з'єднання? Зазвичай веб-сервер під управлінням https не працює на порту 80. Чи є ще щось у помилці, окрім "не вдалося відкрити потік"?
Гордон

1
Наскільки мені відомо, це вся помилка: Попередження: fopen (https: // ...) [function.fopen]: не вдалося відкрити потік: Немає такого файлу чи каталогу в / home / user / public_html / test.php на лінії 993
Джеймс Сімпсон

і дозволити_url_fopen в php.ini встановлено на що?
Гордон

Це дивно. Чи можете ви зробити GET на HTTP та URL-адресі HTTPS, щоб перевірити, чи працює це? без контексту потоку?
Гордон

3

У моєму випадку проблема сталася через те, що WAMP використовував для CLI інший php.ini, ніж Apache, тому ваші налаштування, зроблені через меню WAMP, не стосуються CLI. Просто змініть CLI php.ini і воно працює.


1

Іноді сервер вирішить не відповідати на основі того, що він бачить або не бачить у заголовках запиту http (наприклад, відповідний агент користувача). Якщо ви можете підключитися до браузера, візьміть заголовки, які він надсилає, та імітуйте їх у контексті потоку.


0

Мене застрягли нефункціональні https на IIS. Вирішено:

file_get_contents ('https ..) не завантажується.

  • завантажити https://curl.haxx.se/docs/caextract.html
  • встановити під ..phpN.N / extras / ssl
  • редагуйте php.ini за допомогою:

    curl.cainfo = "C: \ програмні файли \ PHP \ v7.3 \ extras \ ssl \ cacert.pem" openssl.cafile = "C: \ програмні файли \ PHP \ v7.3 \ extras \ ssl \ cacert.pem"

нарешті!


-1

ПЕРЕВІРИТИСЯ, ЯКЩО URL-адреса НЕ ВАЖЕ ТА НЕ

Код у вашому запитанні можна переписати на робочу версію:

function send($packet=NULL, $url) {
// Do whatever you wanted to do with $packet
// The below two lines of code will let you know if https url is up or not
$command = 'curl -k '.$url;
return exec($command, $output, $retValue);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.