Comment faire fonctionner file_get_contents () avec HTTPS?

106

Je travaille sur la configuration du traitement des cartes de crédit et je devais utiliser une solution de contournement pour CURL. Le code suivant fonctionnait bien lorsque j'utilisais le serveur de test (qui n'appelait pas d'URL SSL), mais maintenant, lorsque je le teste sur le serveur de travail avec HTTPS, il échoue avec le message d'erreur «Échec de l'ouverture du flux».

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
la source

Réponses:

89

Essayez le script suivant pour voir s'il existe un wrapper https disponible pour vos scripts 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);

la sortie devrait être quelque chose comme

openssl: yes
http wrapper: yes
https wrapper: yes
wrappers: array(11) {
  [...]
}
VolkerK
la source
@volker C'est pourquoi j'ai demandé allow_url_fopen
Gordon
Eh bien, ce qui est étrange, c'est qu'il indique que openssl est désactivé, mais selon phpinfo (), il est compilé avec, à moins que je ne le voie mal.
James Simpson
phpinfo () vous le dit dans la ligne de configuration ou y a-t-il une section entière appelée "OpenSSL"?
VolkerK
D'accord, c'est juste dans la ligne de configuration, pas dans une section pour cela. Je suppose que c'est le problème?
James Simpson
J'ai tout ça et ça ne marche toujours pas. Et allow_url_fopen. Seules les URL non https fonctionnent à partir de localhost.
Curtis
116

Pour autoriser le wrapper https:

  • l' php_opensslextension doit exister et être activée
  • allow_url_fopen doit être réglé sur on

Dans le fichier php.ini, vous devez ajouter ces lignes s'il n'existe pas:

extension=php_openssl.dll

allow_url_fopen = On
hassan
la source
Les deux sont définis sur Activé dans mon installation mais j'obtiens toujours l'erreur SSL "Avertissement: file_get_contents (): SSL: La poignée de main a expiré dans"
Adamantus
53

Essayez ce qui suit.

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

Remarque: Cela désactive la vérification SSL, ce qui signifie que la sécurité offerte par HTTPS est perdue . N'utilisez ce code que pour des tests / développement local, jamais sur Internet ou sur d'autres réseaux publics. Si ce code fonctionne, cela signifie que le certificat SSL n'est pas fiable ou ne peut pas être vérifié, ce que vous devriez examiner comme un problème distinct.

Benjamin Crouzier
la source
29
Pourquoi désactiver la vérification SSL lors du traitement des cartes de crédit?
Peter
Merci, l'astuce est ici: 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));

Cela vous permettra d'obtenir le contenu de l'url, qu'il s'agisse d'un HTTPS

Dushyant Dagar
la source
Merci! Cela a fonctionné de mon côté. J'ai essayé d'appeler FB Open Graph API :)
decodingpanda
J'essayais d'accéder à un de mes domaines avec un certificat invalide uniquement à des fins de test et même si cela désactive la validation SSL, c'était ce dont j'avais besoin.
carla
Génial! J'essaye depuis 5 jours de télécharger un calendrier airbnb sur mon site de test XAMPP en utilisant file_get_contents, cela a résolu le problème, merci.
JohnnyBeGood
J'ai travaillé pour moi en essayant de me connecter à la boîte de test Vagrant sans certificat HTTP valide sur https. Lien vers les options de contexte SSL PHP définies ici: php.net/manual/en/context.ssl.php ; verify peer = Exige la vérification du certificat SSL utilisé; verify_peer_name = Nécessite la vérification du nom du pair.
Anthony
n'est-ce pas une certification SSL cassante et une faille de sécurité?
webchun
10

Cela est probablement dû au fait que votre serveur cible ne possède pas de certificat SSL valide.

Emil Vikström
la source
Le serveur demandeur n'a pas besoin d'avoir un certificat SSL.
ceejayoz
15
Je n'ai pas dit le serveur demandeur, j'ai dit le serveur cible.
Emil Vikström
2
Cela m'apprendra à écumer. Il h! Veuillez accepter mes excuses et mon vote favorable.
ceejayoz
Le serveur cible possède un certificat SSL valide.
James Simpson
@James, obtenez-vous une erreur si vous essayez de vous connecter avec cURL à la place? Ou est-ce absolument impossible d'essayer?
Emil Vikström
6

Ajoutez simplement deux lignes dans votre fichier php.ini.

extension=php_openssl.dll

allow_url_include = On

ça marche pour moi.

Ritesh Chandora
la source
1
Vous voulez probablement dire allow_url_fopenpuisque la question concerne l'ouverture d'URL, non comprise.
shukshin.ivan
5

J'ai eu la même erreur. La mise allow_url_include = Onen place l'a php.inicorrigé pour moi.

Jim Jones
la source
5

HTTPS est pris en charge à partir de PHP 4.3.0, si vous avez compilé le support d'OpenSSL. Assurez-vous également que le serveur cible dispose d'un certificat valide, que le pare-feu autorise les connexions sortantes et que allow_url_fopendans php.ini est défini sur true.

Gordon
la source
J'ai PHP 5.2.8 avec le support OpenSSL. J'obtiens la même erreur avec ceci, et le serveur cible a un certificat valide.
James Simpson
2
le pare-feu est-il configuré pour autoriser les connexions https sortantes? Habituellement, le serveur Web exécutant https ne fonctionne pas sur le port 80. Y a-t-il autre chose dans l'erreur à part «échec d'ouverture du flux»?
Gordon
1
Pour autant que je sache, c'est l'erreur entière: Avertissement: fopen (https: // ...) [function.fopen]: échec d'ouverture du flux: aucun fichier ou répertoire de ce type dans / home / user / public_html / test.php en ligne 993
James Simpson
et allow_url_fopen dans php.ini est défini sur quoi?
Gordon
C'est étrange. Pouvez-vous faire un GET sur un HTTP et une URL HTTPS pour voir si cela fonctionne? sans le contexte de flux?
Gordon
3

Dans mon cas, le problème était dû au fait que WAMP utilisait un php.ini différent pour la CLI qu'Apache, donc vos paramètres définis via le menu WAMP ne s'appliquent pas à la CLI. Modifiez simplement le php.ini CLI et cela fonctionne.

dtbarne
la source
1

Parfois, un serveur choisit de ne pas répondre en fonction de ce qu'il voit ou ne voit pas dans les en-têtes de requête http (comme un agent utilisateur approprié). Si vous pouvez vous connecter à un navigateur, saisissez les en-têtes qu'il envoie et imitez-les dans le contexte de votre flux.

GZipp
la source
0

J'étais coincé avec des https non fonctionnels sur IIS. Résolu avec:

file_get_contents ('https ..) ne se chargerait pas.

  • télécharger https://curl.haxx.se/docs/caextract.html
  • installer sous ..phpN.N / extras / ssl
  • éditez php.ini avec:

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

enfin!

Teson
la source
-1

POUR VÉRIFIER SI UNE URL EST OU NON

Le code de votre question peut être réécrit comme une version de travail:

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);
}
Homme ordinaire
la source