¿Cómo hacer que file_get_contents () funcione con HTTPS?

106

Estoy trabajando para configurar el procesamiento de tarjetas de crédito y necesitaba usar una solución para CURL. El siguiente código funcionó bien cuando estaba usando el servidor de prueba (que no llamaba a una URL SSL), pero ahora, cuando lo estoy probando en el servidor en funcionamiento con HTTPS, falla con el mensaje de error "no se pudo abrir la transmisión".

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
fuente

Respuestas:

89

Pruebe el siguiente script para ver si hay un contenedor https disponible para sus 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 salida debería ser algo como

openssl: yes
http wrapper: yes
https wrapper: yes
wrappers: array(11) {
  [...]
}
VolkerK
fuente
@volker Por eso pedí allow_url_fopen
Gordon
Bueno, lo extraño es que dice que openssl está desactivado, pero de acuerdo con phpinfo () está compilado con él, a menos que lo vea mal.
James Simpson
phpinfo () te lo dice en la línea de configuración o ¿hay una sección completa llamada "OpenSSL"?
VolkerK
Está bien, solo está en la línea de configuración, no en una sección para él. ¿Supongo que ese es el problema?
James Simpson
Tengo todo eso y todavía no funciona. Y allow_url_fopen. Solo las URL que no son https funcionan desde localhost.
Curtis
116

Para permitir el envoltorio https:

  • la php_opensslextensión debe existir y estar habilitada
  • allow_url_fopen debe establecerse en on

En el archivo php.ini debe agregar estas líneas si no existe:

extension=php_openssl.dll

allow_url_fopen = On
hassan
fuente
Ambos están configurados en Activado en mi instalación, pero sigo recibiendo el error de SSL "Advertencia: file_get_contents (): SSL: Handshake timed out in"
Adamantus
53

Intente lo siguiente.

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: Esto deshabilita la verificación SSL, lo que significa que se pierde la seguridad ofrecida por HTTPS . Utilice este código solo para pruebas / desarrollo local, nunca en Internet u otras redes públicas. Si este código funciona, significa que el certificado SSL no es confiable o no se puede verificar, lo que debe buscar solucionarlo como un problema separado.

Benjamin Crouzier
fuente
29
¿Por qué deshabilitaría la verificación SSL cuando se trata del procesamiento de tarjetas de crédito?
Peter
Gracias, el truco está aquí: 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));

Esto le permitirá obtener el contenido de la URL, ya sea HTTPS

Dushyant Dagar
fuente
¡Gracias! Esto funcionó en mi final. He intentado llamar a FB Open Graph API :)
decodingpanda
Estaba tratando de acceder a un dominio mío con un certificado no válido solo con fines de prueba y, aunque esto deshabilita la validación SSL, era lo que necesitaba.
carla
¡Excelente! He intentado durante 5 días descargar un calendario de airbnb en mi sitio de prueba XAMPP usando file_get_contents, esto resolvió el problema, gracias.
JohnnyBeGood
Me funcionó al intentar conectarme a la caja de prueba Vagrant sin un certificado HTTP válido a través de https. Enlace a las opciones de contexto PHP SSL que se establecen aquí: php.net/manual/en/context.ssl.php ; verify peer = Requiere verificación del certificado SSL utilizado; verify_peer_name = Requiere verificación del nombre del par.
Anthony
¿No es esto romper la certificación SSL y es un agujero de seguridad?
webchun
10

Esto probablemente se deba a que su servidor de destino no tiene un certificado SSL válido.

Emil Vikström
fuente
El servidor solicitante no necesita tener un certificado SSL.
ceejayoz
15
No dije el servidor solicitante, dije el servidor de destino.
Emil Vikström
2
Eso me enseñará a hojear. ¡Je! Por favor acepte mis disculpas y mi voto positivo.
ceejayoz
El servidor de destino tiene un certificado SSL válido.
James Simpson
@James, ¿obtienes un error si intentas conectarte con cURL? ¿O es absolutamente imposible de intentar?
Emil Vikström
6

Simplemente agregue dos líneas en su archivo php.ini.

extension=php_openssl.dll

allow_url_include = On

está trabajando para mí.

Ritesh Chandora
fuente
1
Probablemente te refieres a allow_url_fopenque la pregunta se refiere a la apertura de URL, sin incluir.
shukshin.ivan
5

Yo tenía el mismo error. Establecer allow_url_include = Onen lo php.iniarregló para mí.

Jim Jones
fuente
5

HTTPS es compatible a partir de PHP 4.3.0, si ha compilado en soporte para OpenSSL. Además, asegúrese de que el servidor de destino tenga un certificado válido, el firewall permita conexiones salientes y allow_url_fopenen php.ini esté configurado como verdadero.

Gordon
fuente
Tengo PHP 5.2.8 con soporte OpenSSL. Recibo el mismo error con esto y el servidor de destino tiene un certificado válido.
James Simpson
2
¿Está configurado el cortafuegos para permitir conexiones https salientes? Por lo general, el servidor web que ejecuta https no se ejecuta en el puerto 80. ¿Hay algo más en el error además de "no se pudo abrir la transmisión"?
Gordon
1
Por lo que sé, este es el error completo: Advertencia: fopen (https: // ...) [function.fopen]: no se pudo abrir la secuencia: No existe ese archivo o directorio en / home / user / public_html / test.php en la línea 993
James Simpson
y allow_url_fopen en php.ini se establece en qué?
Gordon
Eso es extraño. ¿Puede hacer un GET en un HTTP y una URL HTTPS para ver si funciona? sin el contexto de la transmisión?
Gordon
3

En mi caso, el problema se debió a que WAMP usaba un php.ini diferente para CLI que Apache, por lo que la configuración realizada a través del menú WAMP no se aplica a CLI. Simplemente modifique el CLI php.ini y funciona.

dtbarne
fuente
1

A veces, un servidor elegirá no responder en función de lo que ve o no ve en los encabezados de solicitud http (como un agente de usuario apropiado). Si puede conectarse con un navegador, tome los encabezados que envía e imítelos en el contexto de su transmisión.

GZipp
fuente
0

Me quedé atrapado con https no funcional en IIS. Resuelto con:

file_get_contents ('https ..) no se cargaba.

  • descargar https://curl.haxx.se/docs/caextract.html
  • instalar bajo ..phpN.N / extras / ssl
  • editar php.ini con:

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

¡finalmente!

Teson
fuente
-1

PARA VERIFICAR SI UNA URL ESTÁ ACTIVADA O NO

El código de su pregunta se puede reescribir como una versión funcional:

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);
}
Hombre común
fuente