Безгрішний server php. У чому різниця між HTTP_HOST і SERVER_NAME в PHP? Створюємо персональний сервер

У Вас в браузері заблокований JavaScript. Дозвольте JavaScript для роботи сайту!

Суперглобальний масив $ _SERVER

У масив $ _SERVER PHP-інтерпретатор поміщає змінні, отримані від сервера. Без даних змінних складно організувати повноцінну підтримку Web-додатків. Нижче наводиться опис найбільш важливих елементів суперглобального масиву $ _SERVER.

зауваження

  • Переглянути повний список елементів масиву $ _SERVER
  • можна або за допомогою функції print_r (), яка роздруковує дамп масиву або за допомогою функції phpinfo (), яка виводить інформацію про PHP-інтерпретатор.

    Array (\u003d\u003e on \u003d\u003e 200 \u003d\u003e on \u003d\u003e htmlweb.ru \u003d\u003e https \u003d\u003e 443 \u003d\u003e close \u003d\u003e Mozilla / 5.0 (compatible; Googlebot / 2.1; + http: //www.google.com/bot. html) \u003d\u003e * / * \u003d\u003e beget \u003d begetok; \u003d\u003e gzip, deflate \u003d\u003e / usr / local / sbin: / usr / local / bin: / usr / sbin: / usr / bin: / sbin: / bin \u003d \u003e \u003d\u003e Apache / 2.4.25 (Debian) mpm-itk / 2.4.7-04 OpenSSL / 1.0.2l \u003d\u003e htmlweb.ru \u003d\u003e 185.12.92.137 \u003d\u003e 80 \u003d\u003e 144.76.78.4 \u003d\u003e / var / www / htmlweb / data / www / htmlweb.ru \u003d\u003e http \u003d\u003e \u003d\u003e /var/www/htmlweb/data/www/htmlweb.ru \u003d\u003e [Email protected] \u003d\u003e. Php \u003d\u003e 35242 \u003d\u003e /php/function/$_server.php \u003d\u003e CGI / 1.1 \u003d\u003e HTTP / 1.0 \u003d\u003e GET \u003d\u003e \u003d\u003e /php/function/%24_server.php \u003d\u003e /index.php \u003d\u003e /index.php \u003d\u003e 1560059525.711 \u003d\u003e 1560059525) 1

    $ _SERVER [ " DOCUMENT_ROOT"]

    Елемент $ _SERVER [ "DOCUMENT_ROOT"] містить шлях до кореневої директорії сервера, якщо скрипт виконується у віртуальному хості, в даному елементі вказується шлях до кореневої директорії віртуального хоста. Тобто в конфігураційному файлі httpd.conf віртуальний хост має директиву DocumentRoot, якій присвоєно значення "D: / main", елемент $ _SERVER [ "DOCUMENT_ROOT"] буде містити значення "D: main".

    $ _SERVER [ " REMOTE_ADDR"]

    В елемент $ _SERVER [ "REMOTE_ADDR"] поміщається IP-адреса клієнта. При тестуванні на локальній машині - ця адреса буде дорівнює 127.0.0.1. Однак при тестуванні в мережі змінна поверне IP-адреса клієнта або останнього проксі-сервера через який клієнт потрапив на сервер. Якщо клієнт використовує проксі-сервер дізнатися його IP-адресу можна за допомогою змінної оточення HTTP_X_FORWARDED_FOR, значення якої можна отримати за допомогою функції getenv ().

    зауваження

    Проксі-сервера є спеціальними проміжними серверами, що надають спеціальний вид послуг: стиснення трафіку, кодування даних, адаптація під мобільні пристрої тощо Серед безлічі проксі-серверів розрізняють так звані анонімні проксі-сервера, які дозволяють приховувати справжній IP-адресу клієнта, такі сервера не повертають змінної оточення HTTP_X_FORWARDED_FOR.

    Витяг змінної оточення HTTP_X_FORWARDED_FOR

    echo @getenv (HTTP_X_FORWARDED_FOR);

    $ _SERVER [ " SCRIPT_FILENAME"]

    В елемент $ _SERVER [ "SCRIPT_FILENAME"] поміщається абсолютний шлях до файлу від кореня диска. Так, якщо сервер працює під управлінням операційної системи Windows, то такий шлях може виглядати наступним чином "d: main estindex.php", тобто шлях вказується від диска, в UNIX-подібної операційної системи шлях вказується від кореневої директорії /, наприклад "/var/share/www/test/index.php".

    /var/www/htmlweb/data/www/сайт/index.php

    $ _SERVER [ " SERVER_NAME"]

    В елемент $ _SERVER [ "SERVER_NAME"] поміщається ім'я сервера, як правило, збігається з доменним ім'ям сайту, розташованого на ньому. наприклад,

    Вміст елемента $ _SERVER [ "SERVER_NAME"] часто збігається з вмістом елемента $ _SERVER [ "HTTP_HOST"]. Крім імені сервера суперглобальний масив $ _SERVER дозволяє з'ясувати ще ряд параметрів сервера, наприклад IP-адреса сервера, прослуховується порт, який Web-сервер встановлений і версію HTTP протоколу. Ця інформація міститься в елементи $ _SERVER [ "SERVER_ADDR"], $ _SERVER [ "SERVER_PORT"], $ _SERVER [ "SERVER_SOFTWARE"] і $ _SERVER [ "SERVER_PROTOCOL"], відповідно. Нижче наводиться приклад з використанням даних елементів.

    Використання елементів масиву $ _SERVER

    echo "Ім'я сервера -". $ _ SERVER [ "SERVER_NAME"]. "
    "; Echo" IP-адреса сервера - ". $ _ SERVER [" SERVER_ADDR "]."
    "; Echo" Порт сервера - ". $ _ SERVER [" SERVER_PORT "]."
    "; Echo" Web-сервер - ". $ _ SERVER [" SERVER_SOFTWARE "]."
    "; Echo" Версія HTTP-протоколу - ". $ _ SERVER [" SERVER_PROTOCOL "]."
    ";

    Ім'я сервера - сайт
    IP-адреса сервера - 185.12.92.137
    Порт сервера - 80
    Web-сервер - Apache / 2.4.25 (Debian) mpm-itk / 2.4.7-04 OpenSSL / 1.0.2l
    Версія HTTP-протоколу - HTTP / 1.0

    $ _SERVER [ " REQUEST_METHOD"]

    В елемент $ _SERVER [ "REQUEST_METHOD"] поміщається метод запиту, який застосовується для виклику скрипта: GET або POST.

    Echo $ _SERVER [ "REQUEST_METHOD"];

    $ _SERVER [ " QUERY_STRING"]

    В елемент $ _SERVER [ "QUERY_STRING"] заносяться параметри, передані скрипту, якщо рядок запиту представляє собою адресу

    Наприклад при зверненні до:
    в елемент $ _SERVER [ "QUERY_STRING"] потрапить весь текст після знаку "?":

    Echo $ _SERVER [ "QUERY_STRING"];

    id \u003d 1 & test \u003d wet & id_theme \u003d 512

    $ _SERVER [ " PHP_SELF"]

    В елемент $ _SERVER [ "PHP_SELF"] поміщається ім'я скрипта, починаючи від кореневої директорії віртуального хоста, тобто якщо рядок запиту представляє собою адресу http://www.mysite.ru/test/index.php?id\u003d1&test\u003dwet&id_theme\u003d512 то елемент $ _SERVER [ "PHP_SELF"] буде містити фрагмент "/Test/index.php". Як правило, цей же фрагмент поміщається в елемент $ _SERVER [ "SCRIPT_NAME"].

    $ _SERVER [ " REQUEST_URI"]

    В елемент $ _SERVER [ "REQUEST_URI"] містить ім'я скрипта, починаючи від кореневої директорії віртуального хоста і параметри, тобто якщо рядок запиту представляє собою адресу: http://www.mysite.ru/test/index.php?id\u003d1&test\u003dwet&id_theme\u003d512 то елемент $ _SERVER [ "REQUEST_URI"] буде містити фрагмент "/Test/index.php?id\u003d1&test\u003dwet&id_theme\u003d512". Для того, щоб відновити в скрипті повну адресу, який поміщений в рядку запиту, досить використовувати комбінацію елементів масиву $ _SERVER, представлену нижче

    Повна адреса до скрипта

    echo "http: //". $ _ SERVER [ "SERVER_NAME"]. $ _ SERVER [ "REQUEST_URI"];

    $ HTTP_SERVER_VARS [видалено]

    (PHP 4\u003e \u003d 4.1.0, PHP 5, PHP 7)

    $ _SERVER - $ HTTP_SERVER_VARS [видалено]Інформація про сервер і середовищі виконання

    опис

    Змінна $ _SERVER - це масив, що містить інформацію, таку як заголовки, шляхи та місця розташування скриптів. Записи в цьому масиві створюються веб-сервером. Немає гарантії, що кожен веб-сервер надасть будь-яку з них; сервер може опустити деякі з них або надати інші, не зазначені тут. Тим не менш, багато ці змінні присутні в "специфікації CGI / 1.1, так що ви можете їх очікувати їх реалізації і в конкретному веб-сервері.

    Змінна $ HTTP_SERVER_VARS містить ту ж початкову інформацію, але вона не суперглобального. (Зауважте, що $ HTTP_SERVER_VARS і $ _SERVER є різними змінними, так що PHP обробляє їх відповідно). Також врахуйте, що "довгі масиви" були видалені в версії PHP 5.4.0, тому $ HTTP_SERVER_VARS більше не існує.

    індекси

    Ви можете знайти (а можете і не знайти) будь-який з наступних елементів в масиві $ _SERVER. Зауважте, що деякі елементи, якщо взагалі такі знайдуться, будуть доступні (або дійсно будуть мати значення), якщо PHP запущений в командному рядку.

    "PHP_SELF" Файл скрипта, який зараз виконується, щодо кореня документів. Наприклад, $ _SERVER [ "PHP_SELF"] в скрипті за адресою http://example.com/foo/bar.php буде /foo/bar.php. Константа __FILE__ містить повний шлях і ім'я файлу поточного (тобто підключеного) файлу. Якщо PHP запущений в командному рядку, ця змінна містить ім'я скрипта, починаючи з PHP 4.3.0. Раніше вона була недоступна. "Argv" Масив аргументів, переданих скрипту. Коли скрипт запущений в командою рядку, це дає C-подібний доступ до параметрів командного рядка. Коли викликається через метод GET, цей масив буде містити рядок запиту. "Argc" Містить кількість параметрів, переданих скрипту (якщо запуск проведений в командному рядку). "GATEWAY_INTERFACE" Містить використовувану сервером версію специфікації CGI; наприклад" CGI / 1.1". "SERVER_ADDR" IP адреса сервера, на якому виконується поточний скрипт. "SERVER_NAME" Ім'я хоста, на якому виконується поточний скрипт. Якщо скрипт виконується на віртуальному хості, тут буде містяться ім'я, визначене для цього віртуального хоста. "SERVER_SOFTWARE" Рядок ідентифікації сервера, зазначена в заголовках, коли відбувається відповідь на запит. "SERVER_PROTOCOL" Ім'я та версія інформаційного протоколу, через який була запрошена сторінка; наприклад " HTTP / 1.0"; "REQUEST_METHOD" Який метод був використаний для запиту сторінки; наприклад " GET", "HEAD", "POST", "PUT".

    зауваження:

    PHP скрипт завершується після посилки заголовків (тобто після того, як здійснює будь-який висновок без буферизації виведення), якщо запит був здійснений методом HEAD.

    "REQUEST_TIME" Тимчасова мітка початку запиту. Доступна, починаючи з PHP 5.1.0. "REQUEST_TIME_FLOAT" Тимчасова мітка початку запиту з точністю до мікросекунд. Доступна, починаючи з PHP 5.4.0. "QUERY_STRING" Рядок запитів, якщо є, за допомогою якої була отримана сторінка. "DOCUMENT_ROOT" Директорія кореня документів, в якій виконується поточний скрипт, в точності та, яка вказана в файлі конфігурації сервера. "HTTP_ACCEPT" вміст заголовка Accept: з поточного запиту, якщо він є. "HTTP_ACCEPT_CHARSET" вміст заголовка Accept-Charset: з поточного запиту, якщо він є. Наприклад: " iso-8859-1, *, utf-8". "HTTP_ACCEPT_ENCODING" вміст заголовка Accept-Encoding: gzip". "HTTP_ACCEPT_LANGUAGE" вміст заголовка Accept-Language: з поточного запиту, якщо він є. Наприклад: " en". "HTTP_CONNECTION" вміст заголовка Connection: з поточного запиту, якщо він є. Наприклад: " Keep-Alive". "HTTP_HOST" вміст заголовка Host: з поточного запиту, якщо він є. "HTTP_REFERER" Адреса сторінки (якщо є), яка привела браузер користувача на цю сторінку. Цей заголовок встановлюється веб-браузером користувача. Не всі браузери встановлюють його і деякі в якості додаткової можливості дозволяють змінювати вміст заголовка HTTP_REFERER. Одним словом, справді йому не можна довіряти. "HTTP_USER_AGENT" вміст заголовка User-Agent: з поточного запиту, якщо він є. Цей рядок містить позначення браузера, яким користувач запросив дану сторінку. Типовим прикладом є рядок: Mozilla / 4.5 (X11; U; Linux 2.2.9 i586). Серед іншого, ви можете використовувати це значення з функцією get_browser () щоб адаптувати висновок вашої сторінки до можливостей браузера користувача "HTTPS" Приймає непорожнє значення, якщо запит був зроблений через протокол HTTPS.

    зауваження: Зверніть увагу, що при використанні ISAPI з IIS значення буде off, Якщо запит не був проведений через протокол HTTPS.

    "REMOTE_ADDR" IP-адреса, з якого користувач переглядає поточну сторінку. "REMOTE_HOST" Віддалений хост, з якого користувач переглядає поточну сторінку. Зворотний перегляд DNS базується на значенні змінної REMOTE_ADDR.

    зауваження: Ваш веб-сервер повинен бути налаштований, щоб створювати цю змінну. Для прикладу, в Apache вам необхідна присутність директиви HostnameLookups On в файлі httpd.conf, щоб ця змінна створювалася. Див. також gethostbyaddr ().

    "REMOTE_PORT" Порт на віддаленій машині, який використовується для зв'язку з веб-сервером. "REMOTE_USER" Аутентіфіцированний користувач. "REDIRECT_REMOTE_USER" Аутентіфіцированний користувач, якщо запит був перенаправлений зсередини. "SCRIPT_FILENAME"

    Абсолютний шлях до скрипту, який в даний момент виконується.

    зауваження:

    Якщо скрипт запускається в командному рядку (CLI), використовуючи відносний шлях, такий як file.php або ../ file.php, змінна $ _SERVER [ "SCRIPT_FILENAME"] буде містити відносний шлях, вказаний користувачем.

    "SERVER_ADMIN" Ця змінна отримує своє значення (для Apache) з директиви конфігураційного файлу сервера. Якщо скрипт запущений на віртуальному хості, це буде значення, визначене для даного віртуального хоста. "SERVER_PORT" Порт на комп'ютері сервера, який використовується веб-сервером для з'єднання. Для установок за замовчуванням, значення буде " 80 "; Використовуючи SLL, наприклад, це значення буде таким, яке налаштоване для з'єднань безпечного HTTP.

    зауваження: Щоб отримати фізичний (реальний) порт в Apache 2, необхідно встановити UseCanonicalName \u003d On і UseCanonicalPhysicalPort \u003d On, Інакше це значення може бути підмінене і не повернути реальної значення фізичного порту. Покладатися на це значення небезпечно в контексті програм, що вимагають посиленої безпеки.

    "SERVER_SIGNATURE" Рядок, що містить версію сервера і ім'я віртуального хоста, які додаються до генеруються сервером сторінок, якщо включено. "PATH_TRANSLATED" Filesystem- (not document root-) based path to the current script, after the server has done any virtual-to-real mapping.

    зауваження: Починаючи з PHP 4.3.2, змінна PATH_TRANSLATED більше не встановлюється неявно в Apache 2 SAPI, в порівнянні з Apache версії 1, де вона встановлюється в те ж саме значення, що і змінна SCRIPT_FILENAME, коли вона не використовується Apache. Ця зміна була зроблена для відповідності специфікації CGI, де змінна PATH_TRANSLATED повинна існувати тільки тоді, коли PATH_INFO визначена. Користувачі Apache 2 можуть використовувати директиву AcceptPathInfo \u003d On в конфігураційному файлі httpd.conf для завдання змінної PATH_INFO.

    "SCRIPT_NAME" Містить шлях, до поточного виконуваного скрипту. Це корисно для сторінок, які повинні вказувати на самих себе. Константа __FILE__ містить повний шлях і ім'я поточного (тобто включається) файлу. "REQUEST_URI" URI, який був переданий для того, щоб отримати доступ до цієї сторінки. Наприклад, " /index.html". "PHP_AUTH_DIGEST" При виконанні HTTP Digest аутентифікації, цієї змінної присвоюється заголовок "Authorization", який надсилається клієнтом (його необхідно потім використовувати для відповідної валідації). "PHP_AUTH_USER" Коли виконується HTTP-аутентифікація, цієї змінної присвоюється ім'я користувача, надане користувачем. "PHP_AUTH_PW" Коли виконується HTTP-аутентифікація, цієї змінної присвоюється пароль, наданий користувачем. "AUTH_TYPE" Коли виконується HTTP-аутентифікація, цієї змінної присвоюється тип аутентифікації, який використовується. "PATH_INFO" Містить будь наданий користувачем шлях, що міститься після імені скрипта, але до рядка запиту, якщо доступно. Наприклад, якщо поточний скрипт запитаний по URL http://www.example.com/php/path_info.php/some/stuff?foo\u003dbar, то змінна $ _SERVER [ "PATH_INFO"] буде містити / Some / stuff?>

    Результатом виконання даного прикладу буде щось подібне.

    • Переклад
    • Tutorial

    Одним з крутейший нововведень в php 5.4 є вбудований сервер, створений спеціально для розробки і тестування. Тепер ви можете писати і тестувати свій код не маючи повноцінного веб-сервера - просто запустіть вбудований сервер, протестуйте свій код, і вимкніть його, коли закінчите.
    Сервер, так само, надає можливість і для творчого використання. Наприклад, ви можете поширювати портативний web-додаток на CD або USB, або навіть як десктопних програм, створене на PHP без використання GTK або інших графічних бібліотек.

    В мануалі PHP підкреслюється, що вбудований сервер призначений для розробки і рекомендується не використовувати його на бойовому сервері. Відсутні будь-які INI директиви відповідають за сервер (за винятком розфарбовування виведення в консолі), і, здається, що основна ідея документації: «у нас тепер теж є Web сервер, відчепіться від нас».
    Незважаючи на це, я вважаю, що вбудовані сервер може бути цінним інструментом для розробки і тестування. Наприклад, на моїй машині я використовую встановлений Apache з кастомной конфігурацією, що підходить для мене, але іноді я хочу спробувати будь-які нові Web-додатки. З вбудованим web-сервером я можу протестувати додаток прямо з папки «downloads» або тимчасової папки і перемістити в звичайну середу, тільки тоді, коли це буде необхідно.
    Але для початку, це не так просто, адже багато написані програми іспользуют.htaccess і mod_rewrite. Але я впевнений, що хтось (може бути один з вас, чому б і ні?) Напише адаптер для цього, і я хотів би бути першим, хто протестують його.
    У цій статті я поясню деякі основні приклади використання вбудованого сервера і покажу вам як зробити його корисним для розробки і тестування.

    Використовуємо вбудований сервер

    Отже, для використання сервера нам необхідний php 5.4 або вище. Для перевірки версії PHP, виконайте:
    php -v
    Так само ви можете визначити чи доступний сервер у вашій збірці виконавши:
    php -h
    і знайдіть там опис параметрів "-S" і "-t", які використовуються тільки для сервера.
    Для перевірки сервера ви можете створити в поточній директорії файл index.php, який буде містити в собі виклик функції phpinfo () і потім запустити сервер:
    $ Php -S 127.0.0.1:8080 PHP 5.4.0RC7 Development Server started at Fri Feb 26 18:49:29 2012 Listening on 127.0.0.1:8080 Document root is / home / ec2-user Press Ctrl-C to quit.
    І тепер ви можете побачити вміст відданої вбудованим web-сервером:

    В консоль ж буде писатися кожен запит клієнта:
    80.180.55.37:36318 : / 80.180.55.37:36584 : /
    Повертаючись назад, розберемо параметр командного рядка "-S", який використовується для вказівки адреси, з якого сервер буде доступний. Можливі значення:
    localhost - сервер буде доступний тільки з локальної машини,
    0.0.0.0 - на будь-якому інтерфейсі машини,
    Будь-який зовнішній або сірий IP - тільки на зазначеному IP
    Параметр "-t" встановлює вказану директорію «directory root». наприклад:
    $ Php -S : 8090 -t / home / ec2-user / public
    Крім того,. ви може вказати ім'я конкретного файлу-роутера. наприклад:
    $ Php -S\u003e localhost or your public IP\u003e: 8080 -t / home / ec2-user / public public / index.php
    Висновок цього роутера буде Парс і виконуватися сервером. Простий приклад:
    Welcome to PHP

    ";
    Якщо скрипт поверне FALSE, тоді запитуваний URI буде оброблятися сервером, який буде видавати запитаний ресурс, або поверне 404 помилку. Якщо скрипт повертає що-небудь ще, висновок скрипта передасться клієнту.
    Хоча даний підхід дає нам більше контролю, є кілька речей, які ви повинні знати. По-перше, PHP сервер віддає тільки мінімальний набір HTTP заголовків:
    Connection: closed Content-Type: text / html Host: aws-dev-01.vtardia.com X-Powered-By: PHP / 5.4.0RC7 D
    Порівняємо це з заголовками, що повертаються сервером Apache:
    Accept-Ranges: bytes Connection: Keep-Alive Content-Length: 631 Content-Type: text / html Date: Sat, 04 Feb 2012 18:24:42 GMT Etag: "bbb99-277-4ace8c5470a40" Keep-Alive: timeout \u003d 15, max \u003d 100 Last-Modified: Wed, 14 Sep 2011 15:54:09 GMT Server: Apache / 2.2.21 (Unix) DAV / 2
    Якщо ваш додаток використовує заголовки, то воно повинно враховувати різницю в development-середовищі і в production.
    По-друге, вбудований сервер має інше SAPI (Server API). Таким чином виконуючи маршрутизацію в index, php ви можете визначити на тестовому або бойовому сервер відбувається звернення до скрипту. php_sapi_name () поверне «cli-server» на вбудованому сервері:
    Існує одна спеціальна INI директива - «cli_server.color». Дана директива повертає розфарбований висновок в консолі. Створіть порожній файл з ім'ям cli-server.ini і вставте цей рядок:
    cli_server.color \u003d on
    Ви можете створити унікальну конфігурацію оточення для вашого сервера, вказавши в вашому INI файлі необхідні директиви. Чи не оголошені директиви візьмуть значення за умовчанням. Зараз ми оголосили тільки одну директиву - cli_server.color.
    Запустити сервер з параметром "-c" із зазначенням INI файлу:
    $ Php -S localhost -c cli-server.ini
    Якщо ваш термінал підтримує кольору, то ви зможете побачити «кольорової» висновок в консолі. 200 статус буде виділено зеленим, 404 - помаранчевим, а помилки сценарію будуть виділені червоним кольором.

    Створюємо персональний сервер

    Тепер, коли ви знаєте все, що необхідно знати про вбудований сервері, давайте зробимо щось круте. Створимо власний портативний сервер!
    Я почну з наступною структури нашого застосування:

    Папка «library» містить код додатка, «public» - коренева директорія, містить index.php і кілька статичних файлів. Особливу увагу в цьому посібнику приділено папці «server», і тому наше додаток буде складатися з простого «Hello Word!» і декількох картинок і css.
    Наша мета - отримати можливість запускати сервер з директорії додатку однією командою, а наш сервер буде піклуватися про роутинг, HTTP заголовках і помилках.
    $ ./start.sh
    Давайте розглянемо сценарій запуску:
    #! / Bin / bash INIFILE \u003d "$ (pwd) /server/server.ini" DOCROOT \u003d "$ (pwd) / public" ROUTER \u003d "$ (pwd) /server/router.php" HOST \u003d 0.0.0.0 PORT \u003d 8080 PHP \u003d $ (which php) if [$? ! \u003d 0]; then echo "Unable to find PHP" exit 1 fi $ PHP -S $ HOST: $ PORT -c $ INIFILE -t $ DOCROOT $ ROUTER
    Я припускаю, що скрипт запускається з директорії додатку, тому INIFILE, DOCROOT, ROUTER визначаються використовуючи pwd. Шлях до php визначається використовуючи команду which. Якщо php не був знайдений в призначеному для користувача $ PATH, то скрипт завершить роботу помилкою.
    Даний спосіб працює досить добре, але давайте надамо користувачеві можливість змінити будь-який з заданих параметрів з командного рядка, наприклад:
    if [! -z $ INIFILE]; then INIFILE \u003d "$ (pwd) /server/server.ini" fi
    Продовжимо, папка «errors» містить файли для повідомлень про HTTP помилки. Ось приклад про 403 помилку: хоча я і використовував тільки HTML, скрипт буде підключений, використовую include, Тому ви можете використовувати будь-який php код:
    403

    403: Forbidden

    Sorry, the requested resource is not accessible.

    Тепер подивимося на router.php. Завдання даного файлу в отриманні та управлінні всіма запитами і передавати їх сервера, тільки якщо даний файл існує. Всі сторінки помилку відображаються шляхом підключення шаблону.
    У перших рядках я визначаю деякі глобальні параметри, такі як DIRECTORY_INDEX, директорія з шаблонами помилок. Параметр date_default_timezone_set () повинен збігатися з настройками ОС, інакше будуть невідповідності між записами в балці і на сервері. Так само я додав список дозволених IP адрес, для підвищення безпеки.
    Функція logAccess () необхідна, тому що коли скрипт роутінга приймає запит лог сервера за замовчуванням ігнорується. Функція приймає тільки код статусу, а формат виведення повністю відповідає формату сервера.
    Наше перше завдання - перевірка безпеки. Якщо IP клієнта не знаходиться в масиві дозволених IP, виводимо повідомлення про помилку і завершуємо роботу скрипта. Нам необхідно віддавати код статусу відмінний від 200 і функція header () не працюватиме в тут, тому ми використовуємо нову функцію - http_response_code.
    Якщо IP клієнта знаходиться в масиві дозволених IP, то наступний наш крок - отримання запитуваної шляху і розширення файлу. Якщо розширення пусте, вважаємо, що користувач запитує папку і будуємо отримуємо шлях, використовуючи певний спочатку DIRECTORY_INDEX.
    На завершення, якщо запитуваний файл існує, повертаємо FALSE, і дозволяємо сервера звернутися до файлу. Якщо ж ні, то з'являється повідомлення про 404 помилку.

    резюме

    Це все. Як бачите, php сервер просто у використанні. Наш персональний сервер дуже простий. Код можна оптимізувати і включати в більш складні і функціональні класи. Happy coding!

    p.s. З радістю прийму критику і зауваження до перекладу в личку.

    Елемент $ _SERVER [ "DOCUMENT_ROOT"] містить шлях до кореневої директорії сервера, якщо скрипт виконується у віртуальному хості, в даному елементі вказується шлях до кореневої директорії віртуального хоста. Тобто в конфігураційному файлі httpd.conf віртуальний хост має директиву DocumentRoot, якій присвоєно значення "D: / main", елемент $ _SERVER [ "DOCUMENT_ROOT"] буде містити значення "D: main".

    Елемент $ _SERVER [ "HTTP_ACCEPT"]

    В елементі $ _SERVER [ "HTTP_ACCEPT"] описуються переваги клієнта щодо типу документа. Вміст цього елемента витягується з HTTP-заголовка Accept, який надсилає клієнт сервера. Вміст даного заголовка може виглядати наступним чином

    Image / gif, image / x-xbitmap, image / jpeg, image / pjpeg, application / x-shockwave-flash, application / vnd.ms-excel, application / msword, * / *

    Заголовок Accept дозволяє уточнити медіа-тип, який вважає за краще отримати клієнт у відповідь на свій запит. Цей заголовок дозволяє повідомити сервер, що відповідь обмежений невеликим безліччю улюблених типів.

    Символ * використовується для групування типів в медіа-ряду. Наприклад, символом * / * задається використання всіх типів, а позначення type / * визначає використання всіх підтипів вибраного типу type.

    зауваження

    Медіа-типи відокремлюються один від одного комами.

    Кожен медіа-ряд характеризується також додатковим набором параметрів. Одним з них є так званий відносний коефіцієнт переваги q, який приймає значення від 0 до 1, відповідно, від менш улюблених типів до більш віддається перевага. Використання декількох параметрів q, дозволяє клієнту повідомити сервер відносну ступінь переваги для того чи іншого медіа-типу.

    зауваження

    За замовчуванням q приймає значення 1. Крім того, від медіа-типу він відокремлюється крапкою з комою.

    Приклад заголовка типу Accept:

    Accept: audio / *; q \u003d 0.2, audio / basic

    В даному заголовку першим йде тип audio / * що включає в себе всі музичні документи і характеризується коефіцієнтом переваги 0.2. Через кому зазначений тип audio / basic, для якого коефіцієнт переваги не вказано і приймає значення за замовчуванням рівне одиниці. Цитуючи цей заголовок можна інтерпретувати в такий спосіб: "Я віддаю перевагу тип audio / basic, але мені можна також надсилати документи будь-якого іншого audio-типу, якщо вони будуть доступні, після зниження коефіцієнта переваги більш ніж на 80%".

    Приклад може бути більш складним.

    Accept: text / plain; q \u003d 0.5, text / html,
    text / x-dvi; q \u003d 0.8, text / x-c

    зауваження

    Слід враховувати, що елемент $ _SERVER [ "HTTP_ACCEPT"] містить таку саму інформацію, але без початкового заголовка Accept.

    Цей заголовок інтерпретується наступним чином: Типи документів text / html і text / xc є переважними, але якщо вони недоступні, тоді клієнт відсилає даний запит, віддасть перевагу text / x-dvi, а, якщо і його немає, то він може прийняти тип text / plain.

    Елемент $ _SERVER [ "HTTP_ACCEPT_LANGUAGE"]

    В елементі $ _SERVER [ "HTTP_ACCEPT_LANGUAGE"] описуються переваги клієнта щодо мови. Дана інформація витягується з HTTP-заголовка Accept-Language, який надсилає клієнт сервера. Можна навести такий приклад:

    Accept-Language: ru, en; q \u003d 0.7

    Який можна інтерпретувати в такий спосіб: клієнт надає перевагу російську мову, але в разі його відсутності згоден приймати документи англійською. Елемент $ _SERVER [ "HTTP_ACCEPT_LANGUAGE"] буде містити таку саму інформацію, але без заголовка Accept-Language:

    Ru, en; q \u003d 0.7

    Вміст елемента $ _SERVER [ "HTTP_ACCEPT_LANGUAGE"] можна використовувати для визначення національної приналежність відвідувачів. Однак результати будуть приблизними, так як багато користувачів використовують англійські варіанти браузерів, які будуть сповіщати сервер про те, що відвідувач воліє лише одну мову - англійську.

    Елемент $ _SERVER [ "HTTP_HOST"]

    В елементі $ _SERVER [ "HTTP_HOST"] міститься ім'я сервера, яке, як правило, збігається з доменним ім'ям сайту, розташованого на сервері. Як правило, ім'я, вказане в даному параметрі збігається з ім'ям $ _SERVER [ "SERVER_NAME"]. У параметрі наводиться лише доменне ім'я без назви протоколу (http: //), тобто

    Www.sofftime.ru

    Елемент $ _SERVER [ "HTTP_REFERER"]

    В елементі $ _SERVER [ "HTTP_REFERER"] наводиться адреса сторінки, з якої відвідувач прийшов на цю сторінку. Перехід повинен здійснюватися за посиланням. Створимо дві сторінки index.php і page.php.

    сторінка index.php

    echo "Посилання на сторінку PHP
    "
    ;
    $ _SERVER [ "HTTP_REFERER"]
    ?>

    Сторінка page.php буде аналогічного змісту, але посилання буде вказувати на сторінку index.php.

    сторінка page.php

    echo "Посилання на сторінку PHP
    "
    ;
    echo "Вміст $ _SERVER [" HTTP_REFERER "] -".
    $ _SERVER [ "HTTP_REFERER"]
    ?>

    При переході з однієї сторінки на іншу, під посиланням буде виводиться адреса сторінки, з якої було здійснено перехід.

    Елемент $ _SERVER [ "HTTP_USER_AGENT"]

    Елемент $ _SERVER [ "HTTP_USER_AGENT"] містить інформацію про тип і версії браузера та операційної системи відвідувача.

    Ось типовий зміст цього рядка: "Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1)". Наявність підрядка "MSIE 6.0" говорить про те, що відвідувач переглядає сторінку за допомогою Internet Explorer версії 6.0. Рядок "Windows NT 5.1" повідомляє, що в якості операційної системи використовується Windows XP.

    зауваження

    Для Windows 2000 елемент $ _SERVER [ "HTTP_USER_AGENT"] виглядає наступним чином: "Mozilla / 4.0 (compatible; MSIE 5.01; Windows NT 5.0)") ", в той час як для Windows XP -" Mozilla / 4.0 (compatible; MSIE 6.0 ; Windows NT 5.1) ".

    Якщо відвідувач скористається браузером Opera, то зміст $ _SERVER [ "HTTP_USER_AGENT"] може виглядати наступним чином: "Mozilla / 4.0 (compatible; MSIE 5.0; Windows 98) Opera 6.04". Підрядок "MSIE 6.0" тут так само присутній, повідомляючи, що браузер Opera є сумісним із браузером Internet Explorer і використовує ті ж динамічні бібліотеки Windows. Тому, при аналізі рядка, що підлягає поверненню браузером, слід мати на увазі, що до Internet Explorer відноситься рядок, що містить підрядок "MSIE 6.0" і не містить підрядка "Opera". Крім того, з цього рядка можна зробити висновок, що користувач використовує операційну систему Windows 98.

    зауваження

    Призначений для користувача агент браузера Firefox може виглядати наступним чином Mozilla / 5.0 (Windows; U; Windows NT 5.1; en-US; rv: 1.8) Gecko / 20051111 Firefox / 1.5.

    При використанні браузера Netscape, зміст елемент $ _SERVER [ "HTTP_USER_AGENT"] може виглядати наступним чином: "Mozilla / 5.0 (X11; U; Linux i686; en-US; rv: 1.4) Gecko / 20030624 Netscape / 7.1". Приналежність до цього браузеру можна визначити за наявністю підрядка "Netscape". Крім того, можна дізнатися, що відвідувач виходить в Інтернет, використовуючи операційну версію Linux, з ядром, оптимізованим під Pentium IV, перебуваючи в графічній оболонці X-Window. Цей механізм зручно використовувати для збору статистичної інформації, яка дозволяє дизайнерам оптимізувати сторінки під найбільш поширені браузери.

    Елемент $ _SERVER [ "REMOTE_ADDR"]

    В елемент $ _SERVER [ "REMOTE_ADDR"] поміщається IP-адреса клієнта. При тестуванні на локальній машині - ця адреса буде дорівнює 127.0.0.1. Однак при тестуванні в мережі змінна поверне IP-адреса клієнта або останнього проксі-сервера через який клієнт потрапив на сервер. Якщо клієнт використовує проксі-сервер дізнатися його IP-адресу можна за допомогою змінної оточення HTTP_X_FORWARDED_FOR, значення якої можна отримати за допомогою функції getenv ().

    зауваження

    Проксі-сервера є спеціальними проміжними серверами, що надають спеціальний вид послуг: стиснення трафіку, кодування даних, адаптація під мобільні пристрої тощо Серед безлічі проксі-серверів розрізняють так звані анонімні проксі-сервера, які дозволяють приховувати справжній IP-адресу клієнта, такі сервера не повертають змінної оточення HTTP_X_FORWARDED_FOR.

    Витяг змінної оточення HTTP_X_FORWARDED_FOR

    echo getenv (HTTP_X_FORWARDED_FOR);
    ?>

    Елемент $ _SERVER [ "SCRIPT_FILENAME"]

    В елемент $ _SERVER [ "SCRIPT_FILENAME"] поміщається абсолютний шлях до файлу від кореня диска. Так, якщо сервер працює під управлінням операційної системи Windows, то такий шлях може виглядати наступним чином "d: main estindex.php", тобто шлях вказується від диска, в UNIX-подібної операційної системи шлях вказується від кореневої директорії /, наприклад "/var/share/www/test/index.php".

    Елемент $ _SERVER [ "SERVER_NAME"]

    В елемент $ _SERVER [ "SERVER_NAME"] поміщається ім'я сервера, як правило, збігається з доменним ім'ям сайту, розташованого на ньому. наприклад,

    Www.сайт

    Вміст елемента $ _SERVER [ "SERVER_NAME"] часто збігається з вмістом елемента $ _SERVER [ "HTTP_HOST"]. Крім імені сервера суперглобальний масив $ _SERVER дозволяє з'ясувати ще ряд параметрів сервера, наприклад IP-адреса сервера, прослуховується порт, який Web-сервер встановлений і версію HTTP протоколу. Ця інформація міститься в елементи $ _SERVER [ "SERVER_ADDR"], $ _SERVER [ "SERVER_PORT"], $ _SERVER [ "SERVER_SOFTWARE"] і $ _SERVER [ "SERVER_PROTOCOL"], відповідно. Нижче наводиться приклад з використанням даних елементів.

    Використання елементів масиву $ _SERVER

    echo "Ім'я сервера -". $ _SERVER [ "SERVER_NAME"]. "
    " ;
    echo "IP-адреса сервера -". $ _SERVER [ "SERVER_ADDR"]. "
    " ;
    echo "Порт сервера -". $ _SERVER [ "SERVER_PORT"]. "
    " ;
    echo "Web-сервер -". $ _SERVER [ "SERVER_SOFTWARE"]. "
    " ;
    echo "Версія HTTP-протоколу -". $ _SERVER [ "SERVER_PROTOCOL"]. "
    " ;
    ?>

    І саме це клієнт фактично використовував як "цільової хост" запиту. SERVER_NAME визначається в конфігурації сервера. Який з них залежить від того, для чого вам це потрібно. Тепер ви повинні розуміти, що це контрольоване клієнтом значення, яке, таким чином, не може бути надійним для використання в бізнес-логікою, а інше є контрольованим сервером значенням, яке є більш надійним. Проте вам необхідно переконатися, що веб-сервер має правильну конфігурацію SERVER_NAME. Взявши Apache HTTPD як приклад, тут витяг з її документації:

    Якщо не вказано ServerName, тоді сервер намагається вивести ім'я хоста, виконавши зворотний пошук по IP-адресою. Якщо жоден порт не вказано в ServerName, тоді сервер буде використовувати порт з вхідного запиту. Для забезпечення оптимальної надійності та передбачуваності ви повинні вказати явне ім'я хоста і порт за допомогою директиви ServerName.

    оновити: Після перевірки відповіді Pekka на ваше запитання, який містить посилання на bobince answer, що PHP завжди буде повертати значення HTTP_HOST для SERVER_NAME, що суперечить моєму власному досвіду PHP 4.x + Apache HTTPD 1.2.x з пару років назад, я підірвав пил від мого поточного XAMPP в Windows XP (Apache HTTPD 2.2.1 з PHP 5.2.8), запустив його, створив сторінку PHP, яка друкує обидва значення, створила тестове додаток Java, використовуючи URLConnection, щоб змінити заголовок Host, і тести навчили мене, що це дійсно (невірно) випадок.

    Після першого підозри PHP і копання в деяких звітах про помилки PHP щодо предмета, я дізнався, що корінь проблеми знаходиться на використовуваному веб-сервері, що він неправильно повернув заголовок HTTP Host, коли була запрошена SERVER_NAME. Таким чином, я перекопав в звіти про помилки Apache HTTPD , використовуючи різні ключові слова щодо суб'єкт, і я нарешті знайшов пов'язану помилку. Це поведінка була введено, тому що навколо Apache HTTPD 1.3. Вам потрібно встановити UseCanonicalName директиву on в запису ServerName в httpd.conf (також перевірте попередження внизу документ!).

    ServerName example.com UseCanonicalName on

    Це спрацювало для мене.

    Узагальнений, SERVER_NAME більш надійний, але ви залежний в конфігурації сервера!

    HTTP_HOST - цільової хост, відправлений клієнтом. Користувач може вільно маніпулювати користувачем. Не потрібно надсилати запит на ваш сайт із запитом HTTP_HOST значення www.stackoverflow.com.

    SERVER_NAME виходить з визначення сервера VirtualHost і тому вважається більш надійним. Його також можна маніпулювати ззовні при певних умовах, пов'язаних з налаштуванням вашого веб-сервера. Див. Цей Це питання SO , Який стосується аспектів безпеки обох варіантів.

    Ви не повинні покладатися на те, щоб бути в безпеці. Проте, що використовувати, дійсно залежить від того, що ви хочете зробити. Якщо ви хочете визначити, в якому домені працює ваш script, ви можете безпечно використовувати HTTP_HOST, поки неприпустимі значення, що надходять від зловмисника, не можуть нічого зламати.

    Зверніть увагу, що якщо ви хочете використовувати IPv6, ви, ймовірно, захочете використовувати HTTP_HOST, а не SERVER_NAME. Якщо ви введете http: // [:: 1] /, змінні середовища будуть наступними:

    HTTP_HOST \u003d [:: 1] SERVER_NAME \u003d :: 1

    Це означає, що якщо ви робите mod_rewrite, наприклад, ви можете отримати неприємний результат. Приклад перенаправлення SSL:

    # SERVER_NAME will NOT work - Redirection to https: // :: 1 / RewriteRule. * Https: //% (SERVER_NAME) / # HTTP_HOST will work - Redirection to https: // [:: 1] / RewriteRule. * Https: //% (HTTP_HOST) /

    Це відноситься ТІЛЬКИ, якщо ви звертаєтеся до сервера без імені хоста.

    якщо ви хочете перевірити через server.php або що ви хочете викликати з наступним:

    Потім отримаєте доступ до всіх дійсною URL-адресами для вашого сайту і перевірте різницю.

    Мені потрібно якийсь час, щоб зрозуміти, що люди мають на увазі під "SERVER_NAME більш надійним". Я використовую загальний сервер і не маю доступу до директив віртуального хоста. Отже, я використовую mod_rewrite в.htaccess для зіставлення різних HTTP_HOST в різних каталогах. У цьому випадку це значення HTTP_HOST має сенс.

    Ситуація аналогічна, якщо ви використовуєте віртуальні хости на основі імен: директива ServerName всередині віртуального хоста просто говорить, яке ім'я хоста буде порівнювати цьому віртуальному хосту. Суть в тому, що в обох випадках ім'я хоста, надане клієнтом під час запиту (HTTP_HOST), має збігатися з ім'ям на сервері, яке саме відображається в каталог. Незалежно від того, чи виконується зіставлення з директивами віртуального хоста або з правилами htaccess mod_rewrite, тут вдруге. У цих випадках HTTP_HOST буде таким же, як SERVER_NAME. Я радий, що Apache налаштований таким чином.

    Однак ситуація відрізняється від віртуальних хостів на базі IP. В цьому випадку і тільки в цьому випадку SERVER_NAME і HTTP_HOST можуть бути різними, тому що тепер клієнт вибирає сервер по IP, а не по імені. Дійсно, можуть бути специфічні зміни, де це важливо.

    Отже, починаючи з цього моменту, я буду використовувати SERVER_NAME, на випадок, якщо мій код буде перенесений в ці специфічні зміни.

    Припускаючи, що у вас є проста настройка (CentOS 7, Apache 2.4.x і PHP 5.6.20) і тільки один веб-сайт (не припускає віртуальний хостинг) ...

    У сенсі PHP $ _SERVER [ "SERVER_NAME"] - це елемент PHP, зареєстрований в суперкласме $ _SERVER на основі вашої конфігурації Apache (директива ** ServerName ** з UseCanonicalName On) в httpd.conf (будь то з включеною конфігурації віртуального хоста файл, що завгодно і т.д.). HTTP_HOST виводиться з заголовка HTTP host. Розглядайте це як для користувача введення. Фільтр і перевірка перед використанням.

    Ось приклад того, де я використовую $ _SERVER [ "SERVER_NAME"] в якості основи для порівняння. Наступний метод відноситься до конкретного дочірньому класу, який я назвав ServerValidator (дочірній елемент Validator). ServerValidator перевіряє шість або сім елементів в $ _SERVER перед їх використанням.

    При визначенні того, чи є HTTP-запит POST, я використовую цей метод.

    Public function isPOST () (return (($ this-\u003e requestMethod \u003d\u003d\u003d "POST") && // Ignore $ this-\u003e hasTokenTimeLeft () && // Ignore $ this-\u003e hasSameGETandPOSTIdentities () && // Ingore ($ this -\u003e httpHost \u003d\u003d\u003d filter_input (INPUT_SERVER, "SERVER_NAME")));)

    До моменту виклику цього методу буде виконуватися вся фільтрація і перевірка відповідних елементів $ _SERVER (і відповідних наборів властивостей).

    ($ This-\u003e httpHost \u003d\u003d\u003d filter_input (INPUT_SERVER, "SERVER_NAME")

    Перевіряє, що значення $ _SERVER [ "HTTP_HOST"] (в кінцевому рахунку отримане з запитаного HTTP-заголовка host) відповідає $ _SERVER [ "SERVER_NAME"].

    Тепер я використовую суперглобальний розмову, щоб пояснити мій приклад, але це тому, що деякі люди не знайомі з INPUT_GET, INPUT_POST і INPUT_SERVER щодо filter_input_array ().

    Суть в тому, що я не обробляю запити POST на моєму сервері, якщо не виконані всі чотири умови. Отже, з точки зору запитів POST відмову в наданні HTTP host заголовка (присутності, перевіреного для більш ранніх) заклинань doom для строгих браузерів HTTP 1.0. Крім того, запитуваний хост повинен відповідати значенням ServerName в httpd.conf, а по розширенню - значенням $ _SERVER ( "SERVER_NAME") в супермаклоне $ _SERVER. Знову ж таки, я б використовував INPUT_SERVER з функціями фільтра PHP, але ви ламали мій дрейф.

    Як зазначено в balusC, SERVER_NAME не є надійним і може бути змінений в конфігурації apache, конфігурації сервера сервера і брандмауера, які можуть перебувати між вами і сервером.

    Наступна функція завжди повертає реальний хост (призначений для користувача збірний хост) без порту, і він майже надійний:

    Function getRealHost () (list ($ realHost,) \u003d explode ( ":", $ _ SERVER [ "HTTP_HOST"]); return $ realHost;)

    поділитися