Jaký je rozdíl mezi HTTP_HOST a SERVER_NAME v PHP? PHP $ _SERVER Global Array Retrieving Environment Proměnná HTTP_X_FORWARDED_FOR
$ _SERVER je jedním z nejdůležitějších předdefinovaných polí v PHP. Obsahuje proměnné přijaté ze serveru interpretem PHP. Každý používal tyto proměnné, nebo je určitě bude používat, protože bez nich je docela obtížné zorganizovat plnou podporu webových aplikací.
Ve svém článku navrhuji tabulku s hlavními proměnnými superglobálního pole $ _SERVER. Tabulka je podobná tabulce vytvořené pro funkce řetězců PHP.
Chcete -li zobrazit všechny prvky pole $ _SERVER, musíte: a) buď zavolat funkci print_r (), která pole vytiskne; b) buď zavolejte funkci phpinfo (), která zobrazí informace o PHP tlumočníkovi.
Stručně o $ HTTP_SERVER_VARS
Pole $ _SERVER superglobal nahrazuje pole $ HTTP_SERVER_VARS v PHP 4.1.0. $ HTTP_SERVER_VARS nyní se nepoužívá, ale stojí za to o tom vědět. Za prvé, stará verze nebyla autoglobální. Druhým rozdílem je, že některé prvky pole $ _SERVER v $ HTTP_SERVER_VARS neexistují, i když ve většině případů jsou jejich proměnné stejné.
Živel |
Stručný popis |
Příklad |
$ _SERVER ["DOCUMENT_ROOT"] |
Obsahuje cestu ke kořenovému adresáři serveru. |
|
$ _SERVER ["HTTP_HOST"] $ _SERVER ["SERVER_NAME"] |
||
$ _SERVER ["SCRIPT_FILENAME"] |
Obsahuje název skriptu, počínaje kořenovým adresářem virtuálního hostitele. |
C: \ složka \ index.php /www/folder/index.php |
$ _SERVER ["PHP_SELF"] $ _SERVER ["SCRIPT_NAME"] |
Obsahuje název skriptu. |
|
$ _SERVER ["REQUEST_URI"] |
Obsahuje název skriptu, počínaje kořenovým adresářem pevného hostitele, a také parametry, které mu byly předány metodou GET. |
/www/folder/index.php?page=2&num=5 |
$ _SERVER ["QUERY_STRING"] |
Obsahuje parametry předané skriptu metodou GET. |
Pro adresu http://site.com/index.php?page=2&num=5 bude výstup |
$ _SERVER ["REQUEST_METHOD"] |
Obsahuje metodu požadavku, která se používá k vyvolání skriptu. |
DOSTAT nebo POŠTA |
$ _SERVER ["HTTP_REFERER"] |
Obsahuje adresu stránky, ze které návštěvník přišel. |
http://yandex.ru/yandsearch |
$ _SERVER ["HTTP_USER_AGENT"] |
Obsahuje typ a verzi prohlížeče a operačního systému návštěvníka. Může také detekovat vyhledávací roboty a značku mobilního telefonu. Níže je uvedeno srovnání značky telefonu a jeho šifry v řetězci. Nokia - NOKIA; Sony Ericsson - ERICSSON nebo SONYERICSSON; Samsung - SAMSUNG nebo SEC-; Motorola - STK; LG - LG nebo LG-; Alcatel - ALCATEL; Panasonic - PANASONIC; Sagem - SAGEM; Pantech - PANTECH; Siemens - SIE; BenQ - BENQ; NEC - NEC; Sharp - SHARP. |
Mozilla / 4.0 (kompatibilní; MSIE 6.0; Windows NT 5.1) ( IE 6aWindows XP) Mozilla / 4.0 (kompatibilní; MSIE 7.0; Windows NT 5.0) Opera 9.50 ( Opera 9.5aWindows 2000) |
$ _SERVER ["REMOTE_ADDR"] |
Obsahuje IP adresu klienta. |
|
$ _SERVER ["SERVER_ADDR"] |
Obsahuje IP adresu serveru. |
|
$ _SERVER ["HTTP_ACCEPT"] |
Popisuje preference klienta pro typ dokumentu. Obsah tohoto prvku je načten z hlavičky Accept HTTP předané serveru klientem. Výstupní formát: typ MIME [[; q], jiný typ MIME [; q] ...] Může existovat několik preferovaných typů MIME, poté jsou odděleny čárkami. * slouží k nastavení šablony, seskupení. q - preferenční koeficient, ve výchozím nastavení 1, se pohybuje od 0 do 1. |
image / jpeg, image / x-xbitmap, application / x-shockwave-flash obraz / *; q = 0,5, obrázek / jpeg (upřednostňuje zhpeg před všemi ostatními formáty) |
$ _SERVER ["HTTP_ACCEPT_LANGUAGE"] |
Podobně jako předchozí prvek, ale související s jazykovými preferencemi. Lze použít k určení národnosti návštěvníků. Odhad však bude přibližný, protože někteří lidé rádi používají anglické verze prohlížečů |
ru, en; q = 0,9 (upřednostňuje ruštinu, ale pokud tam není - a bude stačit angličtina) |
$ _SERVER ["HTTP_ACCEPT_CHARSET"] |
Podobně jako ty předchozí. Obsahuje záhlaví Accept-Charset |
|
$ _SERVER ["HTTP_ACCEPT_ENCODING"] |
Podobné těm předchozím. Obsahuje hlavičku Accept-Encoding |
|
$ _SERVER ["SERVER_PORT"] |
Obsahuje port pro naslouchání serveru. |
|
$ _SERVER ["SERVER_SOFTWARE"] |
Obsahuje informace o webovém serveru. |
Apache / 2.2.4 (Win32) |
$ _SERVER ["SERVER_PROTOCOL"] |
Obsahuje verzi protokolu HTTP. |
|
$ _SERVER ["GATEWAY_INTERFACE"] |
Obsahuje verzi CGI používanou webovým serverem. |
|
$ _SERVER ["REQUEST_TIME"] |
Čas zahájení požadavku webové stránky ve formátu UNIX. K dispozici od PHP 5.1.0 |
Úplná adresa stránky s parametry:
echo "http: //" .SERVER_NAME. $ _ SERVER ["REQUEST_URI"];
?>
Tabulku se všemi funkcemi lze stáhnout z odkazu ve formátu * .doc.
Věnujte zvláštní pozornost proměnné $ _SERVER ["REQUEST_URI"] a nezapomeňte ji zkontrolovat! Faktem je, že jeho použití nemusí být zvlášť bezpečné. Například na vašem webu jsou pomocí tohoto parametru generovány některé adresy URL. Potom můžete napsat řádek http://site.com/index.php do řádku prohlížeče? “>... Zobrazí se okno s obsahem souboru cookie. Tento příklad je neškodný, ale je to díra, přes kterou může hacker díru zneužít například k ukrást data jiného uživatele. Proto - zkontrolujte v proměnné neplatné znaky, zejména> a<.
Pro dnešek snad všechno. Do příště a hezký víkend!
JavaScript je ve vašem prohlížeči blokován. Aby stránka fungovala, povolte JavaScript!
Superglobální pole $ _SERVER
Do pole $ _SERVER Tlumočník PHP vloží proměnné přijaté ze serveru. Bez těchto proměnných je obtížné poskytnout plnou podporu pro webové aplikace. Následuje popis nejdůležitějších prvků superglobálního pole $ _SERVER.
Komentář
Pole (=> on => 200 => on => htmlweb.ru => https => 443 => close => Mozilla /5.0 (kompatibilní; Googlebot /2.1; + http: //www.google.com/bot. html) => * / * => beget = begetok; => gzip, deflate => / usr / local / sbin: / usr / local / bin: / usr / sbin: / usr / bin: / sbin: / bin = > => Apache / 2.4.25 (Debian) mpm-itk / 2.4.7-04 OpenSSL / 1.0.2l => htmlweb.ru => 185.12.92.137 => 80 => 144,78,44 => / var / www / htmlweb/data/www/htmlweb.ru => http => => /var/www/htmlweb/data/www/htmlweb.ru => [chráněno emailem]=>. php => 35242 => /php/function/$_server.php => CGI /1.1 => HTTP /1.0 => GET => => /php/function/%24_server.php => /index.php => /index.php => 1560059525.711 => 1560059525) 1
$ _SERVER [" DOCUMENT_ROOT"]
Prvek $ _SERVER ["DOCUMENT_ROOT"] obsahuje cestu ke kořenovému adresáři serveru, pokud je skript spuštěn ve virtuálním hostiteli, tento prvek určuje cestu ke kořenovému adresáři virtuálního hostitele. Tito. v konfiguračním souboru httpd.conf má virtuální hostitel směrnici DocumentRoot, které je přiřazena hodnota „D: / main“, prvek $ _SERVER [„DOCUMENT_ROOT“] bude obsahovat hodnotu „D: main“.
$ _SERVER [" REMOTE_ADDR"]
Prvek $ _SERVER ["REMOTE_ADDR"] obsahuje IP adresu klienta. Při testování na místním počítači bude tato adresa 127.0.0.1. Při testování v síti však proměnná vrátí IP adresu klienta nebo posledního proxy serveru, přes který se klient dostal na server. Pokud klient používá proxy server, můžete zjistit jeho IP adresu pomocí proměnné prostředí HTTP_X_FORWARDED_FOR, jejíž hodnotu lze získat pomocí funkce getenv ().
Komentář
Proxy servery jsou speciální zprostředkující servery, které poskytují speciální typ služby: komprese provozu, šifrování dat, adaptace pro mobilní zařízení atd. Mezi mnoha proxy servery se rozlišují takzvané anonymní proxy servery, které vám umožňují skrýt skutečnou IP adresu klienta; tyto servery nevracejí proměnnou prostředí HTTP_X_FORWARDED_FOR.
Extrahování proměnné prostředí HTTP_X_FORWARDED_FOR
echo @getenv (HTTP_X_FORWARDED_FOR);
$ _SERVER [" SCRIPT_FILENAME"]
Prvek $ _SERVER ["SCRIPT_FILENAME"] obsahuje absolutní cestu k souboru z kořenového adresáře disku. Pokud tedy na serveru běží operační systém Windows, pak tato cesta může vypadat takto „d: main estindex.php“, tj. cesta je určena z disku, v operačním systému podobném UNIXu je cesta zadána z kořenového adresáře/, například „/var/share/www/test/index.php“.
/var/www/htmlweb/data/www/site/index.php
$ _SERVER [" SERVER_NAME"]
Prvek $ _SERVER ["SERVER_NAME"] obsahuje název serveru zpravidla stejný jako název domény webu, který je na něm umístěn. Například,
Obsah prvku $ _SERVER ["SERVER_NAME"] je často stejný jako obsah prvku $ _SERVER ["HTTP_HOST"]. Kromě názvu serveru vám superglobální pole $ _SERVER umožňuje zjistit řadu parametrů serveru, například IP adresu serveru, naslouchací port, na kterém je nainstalován webový server, a verzi protokolu HTTP . Tyto informace jsou umístěny na $ _SERVER ["SERVER_ADDR"], $ _SERVER ["SERVER_PORT"], $ _SERVER ["SERVER_SOFTWARE"], respektive $ _SERVER ["SERVER_PROTOCOL"]. Níže je uveden příklad použití těchto položek.
Pomocí prvků pole $ _SERVER
echo "Název serveru je". $ _ SERVER ["SERVER_NAME"]. ""; echo" IP serveru je ". $ _ SERVER [" SERVER_ADDR "]."
"; echo" Serverový port je ". $ _ SERVER [" SERVER_PORT "]."
"; echo" Webový server - ". $ _ SERVER [" SERVER_SOFTWARE "]."
"; echo" Verze protokolu HTTP - ". $ _ SERVER [" SERVER_PROTOCOL "]."
";
Název serveru - web
IP serveru - 185.12.92.137
Port serveru - 80
Web server-Apache / 2.4.25 (Debian) mpm-itk / 2.4.7-04 OpenSSL / 1.0.2l
Verze protokolu HTTP - HTTP / 1.0
$ _SERVER [" REQUEST_METHOD"]
Prvek $ _SERVER ["REQUEST_METHOD"] obsahuje metodu požadavku, která se používá k volání skriptu: GET nebo POST.
Echo $ _SERVER ["REQUEST_METHOD"];
$ _SERVER [" ŘETĚZEC DOTAZU"]
Pokud řetězec dotazu je adresa, prvek $ _SERVER ["QUERY_STRING"] obsahuje parametry předané skriptu
Například při odkazu na:
prvek $ _SERVER ["QUERY_STRING"] bude obsahovat veškerý text za znakem "?":
Echo $ _SERVER ["QUERY_STRING"];
id = 1 & test = mokrý & id_theme = 512
$ _SERVER [" PHP_SELF"]
Prvek $ _SERVER ["PHP_SELF"] obsahuje název skriptu, počínaje kořenovým adresářem virtuálního hostitele, tj. pokud je řetězec dotazu adresa http://www.mysite.ru/test/index.php?id=1&test=wet&id_theme=512 pak prvek $ _SERVER ["PHP_SELF"] bude obsahovat úryvek "/test/index.php"... Stejný fragment je obvykle umístěn v prvku $ _SERVER ["SCRIPT_NAME"].
$ _SERVER [" REQUEST_URI"]
Prvek $ _SERVER ["REQUEST_URI"] obsahuje název skriptu, počínaje kořenovým adresářem virtuálního hostitele a parametry, tzn. pokud je řetězec dotazu adresa: http://www.mysite.ru/test/index.php?id=1&test=wet&id_theme=512 pak prvek $ _SERVER ["REQUEST_URI"] bude obsahovat úryvek "/test/index.php?id=1&test=wet&id_theme=512"... K obnovení úplné adresy ve skriptu, který je umístěn v řetězci dotazu, stačí použít kombinaci prvků pole $ _SERVER, které je uvedeno níže
Úplná adresa skriptu
echo "http: //". $ _ SERVER ["SERVER_NAME"]. $ _ SERVER ["REQUEST_URI"];- Překlad
- Tutorial
Jednou z nejlepších nových funkcí v php 5.4 je vestavěný server vytvořený speciálně pro vývoj a testování. Nyní můžete psát a testovat svůj kód, aniž byste měli plný webový server - stačí spustit integrovaný server, otestovat kód a po dokončení jej vypnout.
Server také poskytuje příležitost pro kreativní využití. Můžete například distribuovat přenosnou webovou aplikaci na CD nebo USB, nebo dokonce jako desktopovou aplikaci postavenou v PHP bez použití GTK nebo jiných grafických knihoven.
Manuál PHP zdůrazňuje, že vestavěný server je určen pro vývoj a nedoporučuje se jej používat na produkčním serveru. Za server nejsou zodpovědné žádné směrnice INI (kromě barvení výstupu v konzole) a zdá se, že hlavní myšlenkou dokumentace je: „nyní máme také webový server, nechte nás na pokoji“.
Bez ohledu na to věřím, že integrovaný server může být cenným nástrojem pro vývoj a testování. Například na svém počítači používám předinstalovaný Apache s vlastní konfigurací, která mi vyhovuje, ale někdy chci vyzkoušet nějaké nové webové aplikace. S integrovaným webovým serverem mohu testovat aplikaci přímo ze složky pro stahování nebo dočasné složky a přesunout ji do svého normálního prostředí pouze v případě potřeby.
Ale pro začátek to není tak snadné, protože mnoho písemných aplikací používá .htaccess a mod_rewrite. Ale jsem si jistý, že někdo (možná jeden z vás, proč ne?) Na to napíše adaptér a já bych chtěl být první, kdo to otestuje.
V tomto článku vysvětlím několik základních příkladů použití integrovaného serveru a ukážu vám, jak jej využít pro vývoj a testování.
Používáme vestavěný server
K používání serveru tedy potřebujeme php 5.4 nebo vyšší. Chcete -li zkontrolovat verzi PHP, spusťte:php -v
Můžete také určit, zda je server k dispozici ve vašem sestavení spuštěním:
php -h
a vyhledejte tam popis možností „-S“ a „-t“, které se používají pouze pro server.
Chcete -li zkontrolovat server, můžete v aktuálním adresáři vytvořit soubor index.php, který bude obsahovat volání funkce phpinfo () a poté spustit server:
$ php -S 127.0.0.1:8080 PHP 5.4.0RC7 Development Server spuštěn v pátek 26. února 18:49:29 2012 Poslech na 127.0.0.1:8080 Kořen dokumentu je / home / ec2-user Ukončete stisknutím Ctrl-C.
A nyní můžete vidět obsah obsluhovaný integrovaným webovým serverem:
Každý požadavek klienta bude zapsán do konzoly:
80.180.55.37:36318 : /
80.180.55.37:36584 : /
Když se vrátíme, podívejme se na parametr příkazového řádku "-S", který slouží k určení adresy, ze které bude server přístupný. Možné hodnoty:
localhost- server bude přístupný pouze z místního počítače,
0.0.0.0
- na jakémkoli rozhraní stroje,
Jakákoli externí nebo šedá IP- pouze na zadané IP
Volba -t nastaví zadaný kořenový adresář. Například:
$ php -S
Kromě,. můžete zadat název konkrétního souboru routeru. Například:
$ php -S> localhost nebo vaše veřejná IP>: 8080 -t / home / ec2 -user / public public / index.php
Výstup tohoto routeru bude analyzován a spuštěn serverem. Jednoduchý příklad:
Vítejte v PHP
Pokud skript vrátí FALSE, pak požadovaný URI zpracuje server, který vydá požadovaný zdroj nebo vrátí chybu 404. Pokud skript vrátí cokoli jiného, výstup skriptu bude předán klientovi.
I když nám tento přístup poskytuje větší kontrolu, je zde několik věcí, které byste měli vědět. Za prvé, server PHP odesílá pouze minimální sadu hlaviček HTTP:
Připojení: uzavřeno Typ obsahu: text / html Hostitel: aws-dev-01.vtardia.com X-Powered-By: PHP / 5.4.0RC7 D
Porovnejte to se záhlavími vrácenými serverem Apache:
Rozsahy přijetí: bajty Připojení: Keep-Alive Délka obsahu: 631 Typ obsahu: text / html Datum: So, 04.2.2012 18:24:42 GMT Etag: "bbb99-277-4ace8c5470a40" Keep-Alive: timeout = 15, max = 100 Poslední změna: Středa, 14. září 2011 15:54:09 GMT Server: Apache / 2.2.21 (Unix) DAV / 2
Pokud vaše aplikace používá záhlaví, musí zohlednit rozdíl ve vývojovém a produkčním prostředí.
Za druhé, integrovaný server má jiné SAPI (Server API). Tím, že provedete směrování v indexu, php, můžete definovat volání skriptu na testovacím nebo produkčním serveru. php_sapi_name () vrátí "cli-server" na integrovaném serveru:
Existuje jedna speciální směrnice INI s názvem „cli_server.color“. Tato směrnice vrací barevný výstup do konzoly. Vytvořte prázdný soubor s názvem cli-server.ini a vložte tento řádek:
cli_server.color = zapnuto
Pro svůj server můžete vytvořit jedinečnou konfiguraci prostředí zadáním nezbytných směrnic v souboru INI. Nehlášené směrnice přijmou jejich výchozí hodnoty. Nyní jsme deklarovali pouze jednu směrnici - cli_server.color.
Spusťte server pomocí parametru "-c" určujícího soubor INI:
$ php -S localhost -c cli -server.ini
Pokud váš terminál podporuje barvy, měli byste v konzole vidět „barevný“ výstup. Stav 200 bude zvýrazněn zeleně, 404 oranžově a chyby skriptu budou zvýrazněny červeně.
Vytváříme osobní server
Nyní, když víte vše o vestavěném serveru, pojďme udělat něco skvělého. Vytvořme si vlastní přenosný server!Začnu s následující strukturou naší aplikace:
![](https://i1.wp.com/habrastorage.org/storage2/7c8/481/6a7/7c84816a7c395af5b240fcc4708c8209.jpg)
Složka „knihovna“ obsahuje kód aplikace, „public“ je kořenový adresář, obsahuje index.php a některé statické soubory. Tento tutoriál se zaměří na složku „server“, takže naše aplikace bude sestávat z jednoduchého „Hello Word!“ a pár obrázků a css.
Naším cílem je umět spustit server z adresáře aplikace jedním příkazem a náš server se postará o směrování, záhlaví HTTP a chyby.
$ ./start.sh
Podívejme se na spouštěcí skript:
#! /bin /bash INIFILE = "$ (pwd) /server/server.ini" DOCROOT = "$ (pwd) /public" ROUTER = "$ (pwd) /server/router.php" HOST = 0,0.0,0 PORT = 8080 PHP = $ (který php), pokud [$? ! = 0]; pak ozvěna „Nelze najít PHP“ exit 1 fi $ PHP -S $ HOST: $ PORT -c $ INIFILE -t $ DOCROOT $ ROUTER
Předpokládám, že skript je spuštěn z adresáře aplikace, takže INIFILE, DOCROOT, ROUTER jsou definovány pomocí pwd. Cesta k php je určena pomocí příkazu which. Pokud v $ PATH uživatele nebyl nalezen php, skript selže s chybou.
Funguje to dost dobře, ale dejme uživateli možnost změnit jakýkoli z daných parametrů z příkazového řádku, například:
kdyby [! -z $ INIFILE]; pak INIFILE = "$ (pwd) /server/server.ini" fi
Složka „chyby“ nadále obsahuje soubory pro chybové zprávy HTTP. Zde je příklad chyby 403: ačkoli jsem použil pouze HTML, skript bude zahrnut, já používám zahrnout takže můžete použít libovolný kód php:
403 Přístup odepřen
Litujeme, požadovaný zdroj není přístupný.
Nyní se podívejme na router.php. Úkolem tohoto souboru je přijímat a spravovat všechny požadavky a přenášet je na server, pouze pokud tento soubor existuje. Po připojení šablony se zobrazí všechny chybové stránky.
V prvních řádcích definuji některé globální parametry, například DIRECTORY_INDEX, adresář s chybovými šablonami. Parametr date_default_timezone_set () se musí shodovat s nastavením operačního systému, jinak mezi položkami v protokolu a na serveru budou nekonzistence. Také jsem přidal seznam povolených IP adres pro zlepšení zabezpečení.
Funkce logAccess () je nezbytná, protože když směrovací skript přijme požadavek, protokol serveru je ve výchozím nastavení ignorován. Funkce přijímá pouze stavový kód a výstupní formát je plně v souladu s formátem serveru.
Naším prvním úkolem je kontrola zabezpečení. Pokud adresa IP klienta není v poli povolených adres IP, zobrazte chybovou zprávu a ukončete skript. Musíme zadat stavový kód jiný než 200 a funkce header () zde nebude fungovat, proto používáme novou funkci - http_response_code.
Pokud je IP klienta v poli povolených IP, pak je naším dalším krokem získání požadované cesty a přípony souboru. Pokud je přípona prázdná, předpokládáme, že uživatel požaduje složku a cestu vytvoří pomocí DIRECTORY_INDEX definovaného jako první.
Nakonec, pokud požadovaný soubor existuje, vraťte hodnotu FALSE a povolte serveru přístup k souboru. Pokud ne, zobrazí se chybová zpráva 404.
souhrn
To je všechno. Jak vidíte, php server se snadno používá. Náš osobní server je velmi jednoduchý. Kód lze optimalizovat a začlenit do složitějších a funkčních tříd. Šťastné kódování!p.s. Kritiku a komentáře k překladu rád přijmu osobně.
A to klient ve skutečnosti použil jako „cílového hostitele“ požadavku. SERVER_NAME je definován v konfiguraci serveru. Který z nich závisí na tom, pro co to potřebujete. Nyní byste měli pochopit, že se jedná o hodnotu řízenou klientem, která tedy nemůže být spolehlivá pro použití v obchodní logice, a druhá je hodnota řízená serverem, která je spolehlivější. Musíte však zajistit, aby webový server měl správnou konfiguraci SERVER_NAME. Vezmeme -li jako příklad Apache HTTPD, zde je výňatek z jeho dokumentace:
Pokud není zadán název_serveru, server se pokusí odvodit název hostitele provedením zpětného vyhledávání na IP adrese. Pokud v ServerName není zadán žádný port, server použije port z příchozího požadavku. Pro optimální spolehlivost a předvídatelnost musíte zadat explicitní název hostitele a port pomocí směrnice ServerName.
Obnovit: po zkontrolování Pekkovy odpovědi na vaši otázku, která obsahuje odkaz na bobinceovu odpověď, že PHP vždy vrátí hodnotu HTTP_HOST pro SERVER_NAME, což je v rozporu s mým vlastním PHP 4.x + Apache HTTPD 1.2.x zkušenostmi před několika lety, Odfoukl jsem prach ze svého aktuálního XAMPP v systému Windows XP (Apache HTTPD 2.2.1 s PHP 5.2.8), spustil jej, vytvořil stránku PHP, která vytiskne obě hodnoty, vytvořil testovací aplikaci Java pomocí URLConnection pro změnu hlavičky hostitele, a testy mě naučily, že tomu tak skutečně je (nesprávně).
Po prvním podezření na PHP a kopání do některých Hlášení chyb PHP pokud jde o předmět, zjistil jsem, že kořen problému je na používaném webovém serveru, že při požadavku SERVER_NAME nevrátil správně záhlaví hostitele HTTP. Tak jsem zakopal Hlášení chyb Apache HTTPD použitím různá klíčová slova ohledně předmětu a nakonec jsem našel související chybu. Toto chování bylo zavedeno přibližně od Apache HTTPD 1.3. V položce musíte zapnout direktivu UseCanonicalName
To fungovalo pro mě.
Zevšeobecněno, SERVER_NAME je spolehlivější, ale vy závislý v konfiguraci serveru!
HTTP_HOST je cílový hostitel odeslaný klientem. Uživatel může s uživatelem libovolně manipulovat. Není nutné odeslat požadavek na váš web s požadavkem HTTP_HOST na hodnotu www.stackoverflow.com.
SERVER_NAME pochází z definice serveru VirtualHost, a je proto považován za spolehlivější. Lze jej také za určitých podmínek souvisejících s nastavením webového serveru manipulovat externě. Viz toto Tato SO otázka která se zabývá bezpečnostními aspekty obou možností.
Abyste byli v bezpečí, nemusíte se spoléhat. Který z nich však použít, opravdu závisí na tom, co chcete dělat. Pokud chcete zjistit, na které doméně je váš skript spuštěn, můžete bezpečně použít HTTP_HOST, pokud neplatné hodnoty pocházející od útočníka nemohou nic zlomit.
Všimněte si toho, že pokud chcete používat IPv6, pravděpodobně budete chtít používat HTTP_HOST a ne SERVER_NAME. Pokud zadáte http: // [:: 1] /, proměnné prostředí jsou následující:
HTTP_HOST = [:: 1] SERVER_NAME = :: 1
To znamená, že pokud například provedete mod_rewrite, můžete získat ošklivý výsledek. Příklad přesměrování SSL:
# SERVER_NAME nebude fungovat - přesměrování na https: // :: 1 / RewriteRule. * Https: //% (SERVER_NAME) / # HTTP_HOST bude fungovat - přesměrování na https: // [:: 1] / RewriteRule. * Https: //% (HTTP_HOST) /
Toto POUZE platí, pokud přistupujete k serveru bez názvu hostitele.
pokud chcete zkontrolovat server.php nebo to, co chcete volat, pomocí následujícího:
Poté přejděte ke všem platným adresám URL svého webu a zkontrolujte rozdíl.
Chvíli mi trvalo, než jsem přišel na to, co lidé myslí pod výrazem „SERVER_NAME spolehlivější“. Používám sdílený server a nemám přístup ke směrnicím virtuálního hostitele. Takže používám mod_rewrite v .htaccess k mapování různých HTTP_HOST v různých adresářích. V tomto případě má tato hodnota HTTP_HOST smysl.
Situace je podobná, pokud používáte virtuální hostitele založené na jménech: směrnice ServerName uvnitř virtuálního hostitele jednoduše říká, který název hostitele bude namapován na tohoto virtuálního hostitele. Pointa je, že v obou případech musí název hostitele zadaný klientem během požadavku (HTTP_HOST) odpovídat jménu na serveru, který se sám mapuje do adresáře. To, zda se mapování provádí pomocí směrnic virtuálního hostitele nebo pomocí pravidel htaccess mod_rewrite, je zde sekundární. V těchto případech bude HTTP_HOST stejný jako SERVER_NAME. Jsem rád, že je Apache takto nakonfigurován.
Situace se však liší od virtuálních hostitelů založených na IP. V tomto případě a pouze v tomto případě se SERVER_NAME a HTTP_HOST mohou lišit, protože nyní klient vybírá server podle IP, nikoli podle názvu. Ve skutečnosti mohou existovat speciální konfigurace, kde je to důležité.
Takže od nynějška budu používat SERVER_NAME pro případ, že by se můj kód dostal do těchto speciálních konfigurací.
Za předpokladu, že máte jednoduché nastavení (CentOS 7, Apache 2.4.xa PHP 5.6.20) a pouze jeden web (žádný sdílený hosting) ...
Ve smyslu PHP je $ _SERVER ["SERVER_NAME"] prvek PHP registrovaný v nadtřídě $ _SERVER na základě vaší konfigurace Apache (** směrnice ServerName ** se zapnutým UseCanonicalName) v httpd.conf (ať už z povolené konfigurace virtuálního hostitele soubor, cokoli atd.). HTTP_HOST je odvozeno z hlavičky hostitele HTTP. Považujte to za vstup uživatele. Před použitím filtrujte a zkontrolujte.
Zde je příklad, kde používám $ _SERVER [„SERVER_NAME“] jako základ pro své srovnání. Další metoda je pro konkrétní podřízenou třídu, kterou jsem pojmenoval ServerValidator (podřízený Validator). ServerValidator před použitím ověří šest nebo sedm položek v $ _SERVER.
Při určování, zda je požadavek HTTP POST, používám tuto metodu.
Veřejná funkce isPOST () (return (($ this-> requestMethod === "POST") && // Ignorovat $ this-> hasTokenTimeLeft () && // Ignorovat $ this-> hasSameGETandPOSTIdentities () && // Ingore ($ this -> httpHost === filter_input (INPUT_SERVER, "SERVER_NAME"))));)
V době, kdy je tato metoda volána, bude provedeno veškeré filtrování a ověřování odpovídajících prvků $ _SERVER (a jejich odpovídajících sad vlastností).
($ this-> httpHost === filter_input (INPUT_SERVER, „SERVER_NAME“)
Zkontroluje, zda hodnota $ _SERVER ["HTTP_HOST"] (nakonec odvozená z požadovaného záhlaví hostitele HTTP) odpovídá $ _SERVER ["SERVER_NAME"].
Nyní k vysvětlení mého příkladu používám superglobální konverzaci, ale to je proto, že někteří lidé nejsou obeznámeni s INPUT_GET, INPUT_POST a INPUT_SERVER ve vztahu k filter_input_array ().
Pointa je, že nezpracovávám požadavky POST na svém serveru, pokud nejsou splněny všechny čtyři podmínky. Proto, pokud jde o požadavky POST, odmítnutí poskytnout hlavičku hostitele HTTP (přítomnost zkontrolována dříve), doom spell pro přísné prohlížeče HTTP 1.0... Požadovaný hostitel musí navíc odpovídat hodnotě Název serveru v httpd.conf, a potažmo - hodnota $ _SERVER („SERVER_NAME“) v supermacle $ _SERVER. Opět bych použil INPUT_SERVER s funkcemi filtru PHP, ale porušili jste můj drift.
Jak bylo uvedeno v balusC, SERVER_NAME není spolehlivý a lze jej změnit v konfiguraci apache, konfiguraci serveru a firewallu, které mohou být mezi vámi a serverem.
Následující funkce vždy vrací skutečného hostitele (host zadaný uživatelem) bez portu a je téměř spolehlivá:
Funkce getRealHost () (list ($ realHost,) = explode (":", $ _ SERVER ["HTTP_HOST"]); vrátit $ realHost;)
sdíletPro začátek vylepšíme registrační stránku přidáním možnosti nahrát avatara. Původní obrázek musí být ve formátu jpg, gif nebo png. Také by nemělo být větší než 2 MB. Nebojte se, po jeho komprimaci skriptem bude mít avatar velikost přibližně 3 kb a ve formátu jpg. Otevřete stránku reg.php a přidejte značku < formulář> čára enctype = "vícedílné / formulářové údaje" jako v příkladu: