Come far funzionare file_get_contents () con HTTPS?


106

Sto lavorando alla configurazione dell'elaborazione della carta di credito e avevo bisogno di utilizzare una soluzione alternativa per CURL. Il codice seguente ha funzionato bene quando stavo usando il server di prova (che non chiamava un URL SSL), ma ora quando lo sto testando sul server funzionante con HTTPS, non funziona con il messaggio di errore "Impossibile aprire il flusso".

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

Risposte:


89

Prova il seguente script per vedere se è disponibile un wrapper https per i tuoi script 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);

l'output dovrebbe essere qualcosa di simile

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

@volker Ecco perché ho chiesto allow_url_fopen
Gordon

Beh, ciò che è strano è che dice che openssl è spento, ma secondo phpinfo () è compilato con esso, a meno che non lo vedo sbagliato.
James Simpson

phpinfo () ti dice così nella riga di configurazione o c'è un'intera sezione chiamata "OpenSSL"?
VolkerK

Va bene, è solo nella riga di configurazione, non in una sezione. Immagino sia questo il problema?
James Simpson

Ho tutto questo e ancora non funziona. E allow_url_fopen. Solo gli URL non https funzionano da localhost.
Curtis

116

Per consentire il wrapper https:

  • l' php_opensslestensione deve esistere ed essere abilitata
  • allow_url_fopen deve essere impostato su on

Nel file php.ini dovresti aggiungere queste righe se non esiste:

extension=php_openssl.dll

allow_url_fopen = On

Entrambi sono impostati su On nella mia installazione ma ricevo ancora l'errore SSL "Attenzione: file_get_contents (): SSL: Handshake timeout in"
Adamantus

53

Prova quanto segue.

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

Nota: questo disabilita la verifica SSL, il che significa che la sicurezza offerta da HTTPS viene persa . Utilizzare questo codice solo per test / sviluppo locale, mai su Internet o altre reti pubbliche. Se questo codice funziona, significa che il certificato SSL non è attendibile o non può essere verificato, cosa che dovresti cercare di risolvere come problema separato.


29
Perché disabilitare la verifica SSL quando si ha a che fare con l'elaborazione della carta di credito?
Peter

Grazie, il trucco è qui: 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));

Ciò ti consentirà di ottenere il contenuto dall'URL sia che si tratti di un HTTPS


Grazie! Questo ha funzionato dalla mia parte. Ho provato a chiamare FB Open Graph API :)
decodingpanda

Stavo cercando di accedere a un mio dominio con certificato non valido solo a scopo di test e anche se questo disabilita la convalida SSL, era ciò di cui avevo bisogno.
carla

Grande! Ho provato per 5 giorni a scaricare un calendario airbnb sul mio sito di test XAMPP utilizzando file_get_contents, questo ha risolto il problema, grazie.
JohnnyBeGood

Ha funzionato per me cercando di connettermi alla casella di prova Vagrant senza un certificato HTTP valido su https. Collegamento alle opzioni del contesto SSL di PHP impostate qui: php.net/manual/en/context.ssl.php ; verifica peer = Richiedi la verifica del certificato SSL utilizzato; verifica_peer_name = Richiedi la verifica del nome del peer.
Anthony

non sta violando la certificazione SSL ed è un buco nella sicurezza?
webchun

10

Ciò è probabilmente dovuto al fatto che il server di destinazione non dispone di un certificato SSL valido.


Il server richiedente non ha bisogno di un certificato SSL.
ceejayoz

15
Non ho detto il server richiedente, ho detto il server di destinazione.
Emil Vikström

2
Questo mi insegnerà a scremare. Eh! Per favore accetta le mie scuse e il voto positivo.
ceejayoz

Il server di destinazione dispone di un certificato SSL valido.
James Simpson

@ James, ricevi un errore se provi a connetterti con cURL invece? O è assolutamente impossibile provare?
Emil Vikström

6

Basta aggiungere due righe nel file php.ini.

extension=php_openssl.dll

allow_url_include = On

sta funzionando per me.


1
Probabilmente intendi allow_url_fopenpoiché la domanda riguarda l'apertura dell'URL, escluso.
shukshin.ivan

5

Ho avuto lo stesso errore. Impostazione allow_url_include = Onin php.inifisso per me.


5

HTTPS è supportato a partire da PHP 4.3.0, se hai compilato in supporto per OpenSSL. Inoltre, assicurati che il server di destinazione abbia un certificato valido, il firewall consenta le connessioni in uscita e allow_url_fopenin php.ini sia impostato su true.


Ho PHP 5.2.8 con supporto OpenSSL. Ricevo lo stesso errore con questo e il server di destinazione ha un certificato valido.
James Simpson

2
il firewall è configurato per consentire le connessioni https in uscita? Di solito, il server web che esegue https non viene eseguito sulla porta 80. c'è qualcos'altro nell'errore oltre a "Impossibile aprire il flusso"?
Gordon

1
Per quanto ne so, questo è l'intero errore: Avviso: fopen (https: // ...) [function.fopen]: impossibile aprire lo stream: nessun file o directory in / home / user / public_html / test.php on line 993
James Simpson

e allow_url_fopen in php.ini è impostato su cosa?
Gordon

È strano. Puoi fare un GET su un HTTP e un URL HTTPS per vedere se funziona? senza il contesto dello stream?
Gordon

3

Nel mio caso, il problema era dovuto al fatto che WAMP utilizzava un php.ini diverso per la CLI rispetto ad Apache, quindi le impostazioni effettuate tramite il menu WAMP non si applicano alla CLI. Basta modificare la CLI php.ini e funziona.


1

A volte un server sceglie di non rispondere in base a ciò che vede o non vede nelle intestazioni della richiesta http (come un agente utente appropriato). Se riesci a connetterti con un browser, prendi le intestazioni che invia e imitali nel contesto del tuo flusso.


0

Sono rimasto bloccato con https non funzionante su IIS. Risolto con:

file_get_contents ('https ..) non veniva caricato.

  • scarica https://curl.haxx.se/docs/caextract.html
  • installa sotto ..phpN.N / extras / ssl
  • modifica php.ini con:

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

finalmente!


-1

PER CONTROLLARE SE UN URL È SU O NO

Il codice nella tua domanda può essere riscritto come una versione funzionante:

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);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.