Wie kann file_get_contents () mit HTTPS arbeiten?

106

Ich arbeite an der Einrichtung der Kreditkartenverarbeitung und musste eine Problemumgehung für CURL verwenden. Der folgende Code funktionierte einwandfrei, als ich den Testserver verwendete (der keine SSL-URL aufrief), aber jetzt, wenn ich ihn auf dem Arbeitsserver mit HTTPS teste, schlägt die Fehlermeldung "Stream konnte nicht geöffnet werden" fehl.

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);
}
James Simpson
quelle

Antworten:

89

Versuchen Sie das folgende Skript, um festzustellen, ob für Ihre PHP-Skripte ein https-Wrapper verfügbar ist.

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

Die Ausgabe sollte so etwas wie sein

openssl: yes
http wrapper: yes
https wrapper: yes
wrappers: array(11) {
  [...]
}
VolkerK
quelle
@volker Deshalb habe ich um allow_url_fopen gebeten
Gordon
Nun, was seltsam ist, ist, dass es heißt, openssl ist ausgeschaltet, aber laut phpinfo () ist es damit kompiliert, es sei denn, ich sehe es falsch.
James Simpson
phpinfo () sagt es dir in der Konfigurationszeile oder gibt es einen ganzen Abschnitt namens "OpenSSL"?
VolkerK
Okay, es ist nur in der Konfigurationszeile, kein Abschnitt dafür. Ich denke das ist das Problem?
James Simpson
Ich habe das alles und es funktioniert immer noch nicht. Und allow_url_fopen. Nur Nicht-https-URLs funktionieren von localhost.
Curtis
116

So erlauben Sie den https-Wrapper:

  • Die php_opensslErweiterung muss vorhanden und aktiviert sein
  • allow_url_fopen muss auf eingestellt sein on

In der Datei php.ini sollten Sie diese Zeilen hinzufügen, falls nicht vorhanden:

extension=php_openssl.dll

allow_url_fopen = On
Hassan
quelle
Beide sind in meiner Installation auf Ein gesetzt, aber ich erhalte immer noch den SSL-Fehler "Warnung: file_get_contents (): SSL: Zeitüberschreitung bei Handshake in"
Adamantus
53

Versuche Folgendes.

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

Hinweis: Dadurch wird die SSL-Überprüfung deaktiviert, sodass die von HTTPS angebotene Sicherheit verloren geht . Verwenden Sie diesen Code nur zum Testen / zur lokalen Entwicklung, niemals im Internet oder in anderen öffentlich zugänglichen Netzwerken. Wenn dieser Code funktioniert, bedeutet dies, dass das SSL-Zertifikat nicht vertrauenswürdig ist oder nicht überprüft werden kann. Die Behebung sollten Sie als separates Problem betrachten.

Benjamin Crouzier
quelle
29
Warum sollten Sie die SSL-Überprüfung deaktivieren, wenn Sie sich mit der Kreditkartenverarbeitung befassen?
Peter
Vielen Dank, der Trick ist hier drin: 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));

Auf diese Weise können Sie den Inhalt von der URL abrufen, unabhängig davon, ob es sich um ein HTTPS handelt

Dushyant Dagar
quelle
Vielen Dank! Das hat an meinem Ende funktioniert. Ich habe versucht, die FB Open Graph API aufzurufen :)
decodingpanda
Ich habe nur zu Testzwecken versucht, auf eine meiner Domänen mit ungültigem Zertifikat zuzugreifen, und obwohl dies die SSL-Validierung deaktiviert, war es das, was ich brauchte.
Carla
Toll! Ich habe 5 Tage lang versucht, einen Airbnb-Kalender auf meine XAMPP-Testseite mit file_get_contents herunterzuladen. Dies hat das Problem gelöst, danke.
JohnnyBeGood
Ich habe versucht, eine Verbindung zur Vagrant-Testbox ohne gültiges HTTP-Zertifikat über https herzustellen. Link zu den hier festgelegten PHP-SSL- Kontextoptionen : php.net/manual/en/context.ssl.php ; Verify Peer = Überprüfung des verwendeten SSL-Zertifikats erforderlich; verify_peer_name = Überprüfung des Peer-Namens erforderlich.
Anthony
Ist dies nicht eine Verletzung der SSL-Zertifizierung und eine Sicherheitslücke?
Webchun
10

Dies liegt wahrscheinlich daran, dass Ihr Zielserver kein gültiges SSL-Zertifikat hat.

Emil Vikström
quelle
Der anfordernde Server muss kein SSL-Zertifikat haben.
Ceejayoz
15
Ich habe nicht den anfragenden Server gesagt, sondern den Zielserver.
Emil Vikström
2
Das bringt mir das Überfliegen bei. Heh! Bitte akzeptiere meine Entschuldigung und stimme zu.
Ceejayoz
Der Zielserver verfügt über ein gültiges SSL-Zertifikat.
James Simpson
@ James, bekommst du eine Fehlermeldung, wenn du stattdessen versuchst, eine Verbindung mit cURL herzustellen? Oder ist das absolut unmöglich zu versuchen?
Emil Vikström
6

Fügen Sie einfach zwei Zeilen in Ihre php.ini-Datei ein.

extension=php_openssl.dll

allow_url_include = On

Es funktioniert für mich.

Ritesh Chandora
quelle
1
Sie meinen wahrscheinlich, allow_url_fopenda die Frage das Öffnen von URLs betrifft, nicht eingeschlossen.
shukshin.ivan
5

Ich hatte den gleichen Fehler. Einstellung allow_url_include = Onin php.inies für mich fixiert.

Jim Jones
quelle
5

HTTPS wird ab PHP 4.3.0 unterstützt, wenn Sie OpenSSL unterstützt haben. allow_url_fopenStellen Sie außerdem sicher, dass der Zielserver über ein gültiges Zertifikat verfügt, die Firewall ausgehende Verbindungen zulässt und in php.ini auf true gesetzt ist.

Gordon
quelle
Ich habe PHP 5.2.8 mit OpenSSL-Unterstützung. Ich erhalte den gleichen Fehler, und der Zielserver verfügt über ein gültiges Zertifikat.
James Simpson
2
Ist die Firewall so konfiguriert, dass ausgehende https-Verbindungen zugelassen werden? Normalerweise wird ein Webserver, auf dem https ausgeführt wird, nicht auf Port 80 ausgeführt. Enthält der Fehler außer "Fehler beim Öffnen des Streams" noch etwas anderes?
Gordon
1
Soweit ich weiß, ist dies der gesamte Fehler: Warnung: fopen (https: // ...) [function.fopen]: Stream konnte nicht geöffnet werden: Keine solche Datei oder kein solches Verzeichnis in / home / user / public_html / test.php in Zeile 993
James Simpson
und allow_url_fopen in php.ini ist auf was gesetzt?
Gordon
Das ist seltsam. Können Sie ein GET auf einer HTTP- und einer HTTPS-URL durchführen, um zu sehen, ob dies funktioniert? ohne den Stream-Kontext?
Gordon
3

In meinem Fall war das Problem darauf zurückzuführen, dass WAMP eine andere php.ini für CLI als Apache verwendete, sodass Ihre über das WAMP-Menü vorgenommenen Einstellungen nicht für CLI gelten. Ändern Sie einfach die CLI php.ini und es funktioniert.

dtbarne
quelle
1

Manchmal entscheidet sich ein Server dafür, nicht zu antworten, basierend auf dem, was er in den HTTP-Anforderungsheadern sieht oder nicht (z. B. einem geeigneten Benutzeragenten). Wenn Sie eine Verbindung mit einem Browser herstellen können, greifen Sie auf die von ihm gesendeten Header zu und ahmen Sie sie in Ihrem Stream-Kontext nach.

GZipp
quelle
0

Ich war mit nicht funktionierenden https auf IIS festgefahren. Gelöst mit:

file_get_contents ('https ..) wurde nicht geladen.

  • Laden Sie https://curl.haxx.se/docs/caextract.html herunter
  • Installieren Sie unter ..phpN.N / extras / ssl
  • bearbeiten Sie php.ini mit:

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

endlich!

Teson
quelle
-1

PRÜFEN, ob eine URL aktiv ist oder nicht

Der Code in Ihrer Frage kann in eine Arbeitsversion umgeschrieben werden:

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);
}
Gewöhnlicher Mensch
quelle