Jak zmusić file_get_contents () do pracy z HTTPS?


106

Pracuję nad skonfigurowaniem przetwarzania kart kredytowych i muszę zastosować obejście dla CURL. Poniższy kod działał dobrze, gdy korzystałem z serwera testowego (który nie wywoływał adresu URL SSL), ale teraz, gdy testuję go na działającym serwerze z HTTPS, kończy się niepowodzeniem z komunikatem o błędzie „nie udało się otworzyć strumienia”.

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);
}

Odpowiedzi:


89

Wypróbuj poniższy skrypt, aby sprawdzić, czy jest dostępne opakowanie https dla twoich skryptów 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);

wyjście powinno wyglądać mniej więcej tak

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

@volker Dlatego poprosiłem o allow_url_fopen
Gordon

Cóż, dziwne jest to, że mówi, że openssl jest wyłączone, ale zgodnie z phpinfo () jest z nim skompilowane, chyba że widzę to źle.
James Simpson

phpinfo () powie ci to w linii konfiguracji, czy też jest cała sekcja o nazwie „OpenSSL”?
VolkerK

Okay, to jest tylko w konfiguracji, a nie w jej sekcji. Myślę, że to jest problem?
James Simpson

Mam to wszystko i nadal nie działa. I allow_url_fopen. Tylko adresy URL inne niż https działają z lokalnego hosta.
Curtis,

116

Aby zezwolić na opakowanie https:

  • php_opensslrozszerzenie musi istnieć i być włączony
  • allow_url_fopen musi być ustawiony na on

W pliku php.ini powinieneś dodać te linie, jeśli nie istnieje:

extension=php_openssl.dll

allow_url_fopen = On

Obie są włączone w mojej instalacji, ale nadal
pojawia się

53

Spróbuj wykonać następujące czynności.

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;
}

Uwaga: wyłącza weryfikację SSL, co oznacza, że bezpieczeństwo oferowane przez HTTPS zostaje utracone . Używaj tego kodu tylko do testowania / lokalnego programowania, nigdy w Internecie lub innych sieciach publicznych. Jeśli ten kod działa, oznacza to, że certyfikat SSL nie jest zaufany lub nie można go zweryfikować, co należy rozwiązać jako osobny problem.


29
Dlaczego miałbyś wyłączyć weryfikację SSL podczas przetwarzania kart kredytowych?
Peter

Dziękuję, sztuczka jest tutaj: curl_setopt ($ ch, CURLOPT_SSL_VERIFYPEER, FALSE);
Dylan B

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));

Umożliwi to pobranie treści z adresu URL, niezależnie od tego, czy jest to HTTPS


Dzięki! To zadziałało na mój koniec. Próbowałem wywołać FB Open Graph API :)
decodingpanda

Próbowałem uzyskać dostęp do mojej domeny z nieprawidłowym certyfikatem tylko w celach testowych i chociaż to wyłącza weryfikację SSL, tego potrzebowałem.
Carla

Wspaniały! Od 5 dni próbuję pobrać kalendarz airbnb z mojej witryny testowej XAMPP za pomocą pliku_get_contents. Dzięki temu problem został rozwiązany.
JohnnyBeGood

Udało mi się połączyć się z urządzeniem testowym Vagrant bez ważnego certyfikatu HTTP przez https. Link do ustawianych tutaj opcji kontekstu PHP SSL: php.net/manual/en/context.ssl.php ; verify peer = Wymagaj weryfikacji używanego certyfikatu SSL; verify_peer_name = Wymagaj weryfikacji nazwy partnera.
Anthony

czy nie jest to zerwanie certyfikatu SSL i czy jest to luka w zabezpieczeniach?
webchun

10

Jest to prawdopodobnie spowodowane tym, że serwer docelowy nie ma ważnego certyfikatu SSL.


Serwer wysyłający żądanie nie musi mieć certyfikatu SSL.
ceejayoz

15
Nie powiedziałem serwera żądającego, powiedziałem serwer docelowy.
Emil Vikström

2
To nauczy mnie przeglądać. Heh! Proszę przyjąć moje przeprosiny i zagłosować.
ceejayoz

Serwer docelowy ma ważny certyfikat SSL.
James Simpson

@James, czy podczas próby połączenia z cURL pojawia się błąd? A może jest to absolutnie niemożliwe?
Emil Vikström

6

Po prostu dodaj dwie linie do pliku php.ini.

extension=php_openssl.dll

allow_url_include = On

to działa dla mnie.


1
Prawdopodobnie masz na myśli, allow_url_fopenponieważ pytanie dotyczy otwierania adresu URL, bez uwzględniania.
shukshin.ivan

5

Miałem ten sam błąd. Ustawienie allow_url_include = Onna php.inistałe to dla mnie.


5

HTTPS jest obsługiwany począwszy od PHP 4.3.0, jeśli skompilowałeś obsługę OpenSSL. Upewnij się również, że serwer docelowy ma ważny certyfikat, zapora sieciowa zezwala na połączenia wychodzące, allow_url_fopenaw php.ini jest ustawiona na true.


Mam PHP 5.2.8 z obsługą OpenSSL. Otrzymuję ten sam błąd, a serwer docelowy ma ważny certyfikat.
James Simpson

2
czy firewall jest skonfigurowany tak, aby zezwalał na wychodzące połączenia HTTPS? Zwykle serwer WWW z protokołem https nie działa na porcie 80. Czy w błędzie jest coś jeszcze oprócz „nieudanego otwarcia strumienia”?
Gordon

1
O ile wiem, to jest cały błąd: Ostrzeżenie: fopen (https: // ...) [function.fopen]: nie udało się otworzyć strumienia: nie ma takiego pliku lub katalogu w / home / user / public_html / test.php w linii 993
James Simpson

a allow_url_fopen w php.ini jest ustawione na co?
Gordon

To dziwne. Czy możesz wykonać GET na adresach URL HTTP i HTTPS, aby sprawdzić, czy to działa? bez kontekstu strumienia?
Gordon

3

W moim przypadku problem wynikał z tego, że WAMP używał innego php.ini dla CLI niż Apache, więc ustawienia dokonane za pomocą menu WAMP nie dotyczą CLI. Po prostu zmodyfikuj CLI php.ini i działa.


1

Czasami serwer nie odpowiada na podstawie tego, co widzi lub czego nie widzi w nagłówkach żądań http (na przykład odpowiedni agent użytkownika). Jeśli możesz połączyć się z przeglądarką, chwyć wysyłane przez nią nagłówki i naśladuj je w kontekście swojego strumienia.


0

Utknąłem z niedziałającym protokołem HTTPS w usługach IIS. Rozwiązany:

file_get_contents („https ..) nie wczytuje się.

  • pobierz https://curl.haxx.se/docs/caextract.html
  • zainstaluj pod ..phpN.N / extras / ssl
  • edytuj php.ini za pomocą:

    curl.cainfo = "C: \ Program Files \ PHP \ v7.3 \ extras \ ssl \ cacert.pem" openssl.cafile = "C: \ Program Files \ PHP \ v7.3 \ extras \ ssl \ cacert.pem"

Wreszcie!


-1

ABY SPRAWDZIĆ, CZY URL JEST, CZY NIE JEST

Kod w Twoim pytaniu można przepisać do działającej wersji:

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);
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.