query parser parse hacer convertir como php url-parsing

php - parser - ¿Es $_SERVER[''REQUEST_SCHEME''] confiable?



php build url (7)

Hace poco buscaba una manera de determinar correctamente el protocolo, bajo qué solicitud de URL se suministraba al servidor.

Miré a través de parse_url() y aunque $_SERVER variable superglobal, y encontré esto:

<?php header(''Content-Type: text/plain''); print_r($_SERVER); ?>

Salida:

[REQUEST_SCHEME] => http

Sin embargo, no pude encontrarlo en $_SERVER o Google. Sin embargo, pude encontrar this pregunta. Q # 1: Si $_SERVER[''REQUEST_SCHEME''] no se documentó, ¿es probable que no sea confiable o se pueda confiar?

VC9 PHP 5.4.14 TS usando VC9 PHP 5.4.14 TS en windows para desarrollo. Pero mi producción está bajo ubuntu. Q # 2: ¿Esta propiedad también está disponible bajo ubuntu linux también?


Como esta variable no está disponible en todas las versiones de servidor, no es confiable probarla solo . En su lugar, puede cambiar su código PHP para probar dos variables de entorno de servidor más, que también pueden indicar que se está utilizando https, como se muestra a continuación:

if ( (! empty($_SERVER[''REQUEST_SCHEME'']) && $_SERVER[''REQUEST_SCHEME''] == ''https'') || (! empty($_SERVER[''HTTPS'']) && $_SERVER[''HTTPS''] == ''on'') || (! empty($_SERVER[''SERVER_PORT'']) && $_SERVER[''SERVER_PORT''] == ''443'') ) { $server_request_scheme = ''https''; } else { $server_request_scheme = ''http''; }

Como lo señala toxalot, REQUEST_SCHEME es una variable nativa del servidor web Apache desde su versión 2.4. Apache 2.2 no lo tiene (vea las variables del servidor Apache 2.2) y Microsoft IIs 8.5 tampoco lo tiene (vea IIS 8.5 Server Variables) . Naturalmente, si el servidor no establece una variable, PHP no la incluirá en su matriz global $ _SERVER.

Afortunadamente, para compatibilidad con códigos basados ​​exclusivamente en la comprobación REQUEST_SCHEME, puede crear esta variable en Apache 2.2 editando todos sus archivos de configuración de host (httpd.conf, ssl.conf, 000-default.conf, vhosts.conf), agregando las siguientes líneas :

# FOR HOSTS LISTENING AT PORT 80 SetEnvIf Request_Protocol ^HTTP/ REQUEST_SCHEME=http # FOR HOSTS LISTENING AT PORT 443 SetEnvIf Request_Protocol ^HTTP/ REQUEST_SCHEME=https

El código anterior presupone el uso de un vhost para cada protocolo (una buena práctica en Apache: vea this y that ).


En la nueva versión de Nginx, establece de manera predeterminada el fastcgi_param REQUEST_SCHEME $scheme .


Es difícil probar que es confiable, pero es fácil demostrar que no es confiable (si solo pudiera proporcionar un caso que no funciona). Y puedo probar que no es confiable porque no funciona con IIS 7.0 + PHP 5.3


Este valor depende de su servidor web. Si usa nginx (v1.10), en el archivo /etc/nginx/fastcgi_params puede ver las siguientes líneas:

fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty;

En general, estos valores predeterminados son suficientes. Pero es posible que no funcione, puedes forzar estos valores en tu vhost:

include fastcgi_params; fastcgi_param REQUEST_SCHEME https; fastcgi_param HTTPS On;

Si usas Apache, puedes echarle un vistazo a la respuesta de toxalot


La variable de entorno REQUEST_SCHEME está documentada en la página mod_rewrite de Apache . Sin embargo, no estuvo disponible hasta Apache 2.4.

Solo tengo Apache 2.2, así que creé una variable de entorno. Agregué lo siguiente a la parte superior de mi archivo .htaccess.

RewriteEngine on # Set REQUEST_SCHEME (standard environment variable in Apache 2.4) RewriteCond %{HTTPS} off RewriteRule .* - [E=REQUEST_SCHEME:http] RewriteCond %{HTTPS} on RewriteRule .* - [E=REQUEST_SCHEME:https]

Ahora puedo usar

  • %{ENV:REQUEST_SCHEME} en otras condiciones y reglas de reescritura
  • $_SERVER[''REQUEST_SCHEME''] en mi código PHP

No tengo que hacer comprobaciones condicionales adicionales desordenadas en todas partes, y mi código PHP es compatible con versiones anteriores. Cuando se actualiza Apache, puedo cambiar mi archivo .htaccess.

No sé cómo aplicarías esto a un entorno de Windows. Probablemente esta no sea una buena solución para código distribuido, pero funciona bien para mis necesidades.


Mejorando la sugerencia de toxalot para los usuarios de CloudFlare:

RewriteEngine on RewriteCond %{HTTPS} !on [OR] RewriteCond %{HTTP:CF-Visitor} ''"scheme":"http"'' RewriteRule .* - [E=REQUEST_SCHEME:http] RewriteCond %{HTTPS} on [OR] RewriteCond %{HTTP:CF-Visitor} ''"scheme":"https"'' RewriteRule .* - [E=REQUEST_SCHEME:https]


Yo tampoco pude encontrar una referencia a REQUEST_SCHEME , pero si está buscando determinar si una solicitud fue hecha por http: o https: entonces puede usar $_SERVER[''HTTPS''] , que está configurado como no -valor vacío si https: hizo una solicitud https: Está documentado en el sitio PHP here