Двуликий request_uri или в поисках корректного http/1.1 сервера

5.1 Строка запроса (Request-Line).

Строка запроса (Request-Line) начинается с лексемы метода, затем следует запрашиваемый URI (Request-URI), версия протокола и CRLF. Эти элементы разделяются SP. В строке запроса (Request-Line) не допустимы CR и LF, исключение составляет конечная последовательность CRLF.

          Request-Line   = Method SP Request-URI SP HTTP-Version CRLF

5.1.1 Метод (Method).

Лексема метода указывает метод, который нужно применить к ресурсу, идентифицированному запрашиваемым URI (Request-URI). Метод чувствителен к регистру.

          Method         = "OPTIONS"                ; 
                         | "GET"                    ; 
                         | "HEAD"                   ; 
                         | "POST"                   ; 
                         | "PUT"                    ; 
                         | "DELETE"                 ; 
                         | "TRACE"                  ; 
                         | extension-method

          extension-method = token

Список методов, применимых к ресурсу, может быть указан в поле заголовка Allow (). Возврашаемый код состояния ответа всегда сообщает клиенту, допустим ли метод для ресурса в настоящее время, так как набор допустимых методов может изменяться динамически. Серверам СЛЕДУЕТ возвратить код состояния 405 (Метод не дозволен, Method Not Allowed), если метод известен серверу, но не применим для запрошенного ресурса, и 501 (Не реализовано, Not Implemented), если метод не распознан или не реализован сервером. Список методов, известных серверу, может быть указан в поле заголовка ответа Public ().

Методы GET и HEAD ДОЛЖНЫ поддерживаться всеми универсальными (general-purpose) серверами. Остальные методы опциональны; однако, если вышеупомянутые методы реализованы, то они ДОЛЖНЫ иметь семантику, описанную в разделе 9.

5.1.2 Запрашиваемый URI (Request-URI).

Запрашиваемый URI (Request-URI) — это Единообразный Идентификатор Ресурса (URL, ), который идентифицирует ресурс запроса.

          Request-URI    = "*" | absoluteURI | abs_path

Три опции для запрашиваемого URI (Request-URI) зависят от характера запроса. Звездочка «*» означает, что запрос обращается не к специфическому ресурсу, а к серверу непосредственно, и допускается только в том случае, когда используемый метод не обязательно обращается к ресурсу. В качестве примера:

          OPTIONS * HTTP/1.1

absoluteURI необходим, когда запрос производится через прокси-сервер. Прокси-сервер перенаправляет запрос на сервер или обслуживает его, пользуясь кэшем, и возвращает ответ

Обратите внимание, что прокси-сервер МОЖЕТ переслать запрос другому прокси-серверу или непосредственно серверу, определенному absoluteURI. Чтобы избежать зацикливания запроса прокси-сервер ДОЛЖЕН быть способен распознавать все имена сервера, включая любые псевдонимы, локальные разновидности, и числовые IP адреса. Request-Line может быть, например, таким:

          GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1

Чтобы обеспечить переход к absoluteURI во всех запросах в будущих версиях HTTP, все HTTP/1.1 серверы ДОЛЖНЫ принимать absoluteURI в запросах, хотя HTTP/1.1 клиенты будут генерировать их только в запросах к прокси-серверам.

Наиболее общая форма Request-URI — та, которая используется для идентификации ресурса на первоначальном сервере или шлюзе. В этом случае абсолютный путь URI (смотрите , abs_path) ДОЛЖЕН быть передан как Request-URI, а сетевое расположение URI (net_loc) ДОЛЖНО быть передано в поле заголовка Host. Для последнего примера клиент, желающий получить ресурс непосредственно с первоначального сервера должен создать TCP соединение на 80 порт хоста «www.w3.org» и послать строки:

          GET /pub/WWW/TheProject.html HTTP/1.1
          Host: www.w3.org

Если прокси-сервер получает запрос без пути в Request-URI, и метод запроса допускает форму запроса «*», то последний прокси-сервер в цепочке запросов ДОЛЖЕН передать запрос, в котором Request-URI равен «*». Например запрос

          OPTIONS http://www.ics.uci.edu:8001 HTTP/1.1
          OPTIONS * HTTP/1.1
          Host: www.ics.uci.edu:8001

Request-URI передается в формате, определенном в . Первоначальный сервер ДОЛЖЕН декодировать Request-URI, чтобы правильно интерпретировать запрос. Серверам СЛЕДУЕТ отвечать на недопустимые Request-URI соответствующим кодом состояния.

В запросах, которые передаются далее, прокси-сервера никогда НЕ ДОЛЖНЫ перезаписывать часть «abs_path» запрашиваемого URI (Request-URI), за исключением случая, отмеченного выше, когда пустой abs_path заменяется на «*», независимо от внутренней реализации прокси-сервера.

Обратите внимание: правило «ничто не перезаписывать» предохраняет прокси-сервера от изменения значения запроса, в котором первоначальный сервер неправильно использует не зарезервированные символы URL для своих целей. Реализаторам следует знать, что некоторые до-HTTP/1.1 прокси-сервера, как известно, перезаписывали Request-URI.

5.3 Поля заголовка запроса.

Поля заголовка запроса позволяют клиенту передавать серверу дополнительную информацию о запросе и о самом клиенте. Эти поля действуют как модификаторы запроса с семантикой, эквивалентной параметрам вызова методов в языках программирования.

          request-header = Accept                   ; 
                         | Accept-Charset           ; 
                         | Accept-Encoding          ; 
                         | Accept-Language          ; 
                         | Authorization            ; 
                         | From                     ; 
                         | Host                     ; 
                         | If-Modified-Since        ; 
                         | If-Match                 ; 
                         | If-None-Match            ; 
                         | If-Range                 ; 
                         | If-Unmodified-Since      ; 
                         | Max-Forwards             ; 
                         | Proxy-Authorization      ; 
                         | Range                    ; 
                         | Referer                  ; 
                         | User-Agent               ; 

Имена полей заголовка запроса (Request-header) могут быть надежно расширены только в сочетании с изменением версии протокола. Однако, новые или экспериментальные поля заголовка могут получить семантику полей заголовка запроса (Request-header), если все стороны соединения распознают их как поля заголовка запроса (Request-header). Нераспознанные поля заголовка обрабатываются как поля заголовка объекта (entity-header).

Copyright    1998 Alex Simonoff (http://www.omsk.com/Leshik/), All Rights Reserved.

Пояснение на примерах

1. Многие спрашивают, для чего нужен — $_SERVER — в интернете практически не найти, а лучше смотрите пример:


Такой код может выдать такой ответ: Web-сервер — Apache. То есть вы поняли для чего он нужен, едем дальше…

2. $_SERVER — необходим для вывода информации об операционной системе клиента и версии и названии браузера:

Такой код может выдать такой ответ(только то, что в кавычках): Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0. Собирая данную информацию, можно оптимизировать свой сайт под наиболее востребованные браузеры.

3. $_SERVER — показывает имя сервера, которое совпадает с доменом без http и слешей, только имя.

Такой код может выдать такой ответ: saitsozdanie.ru — то есть как видим, что http:// опускается

$_SERVER — зачастую показывает практически тоже самое;

4. $_SERVER — используется для указания информации «откуда человек пришел» — а, именно, с какой страницы.

Такой код может выдать такой ответ: http://yandex.ru/clck/…. и так далее, если вы перешли на мой сайт к примеру с яндекса из поиска. Очень полезная функция получается для оценки трафика с поисковиков.

5. Использование $_SERVER — покажет вам предпочтения клиента относительно типа документа. Указание заголовка Accept позволяет уточнить желаемый медиа-тип.

Такой код может выдать такой ответ: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8.

Где q — это относительный коэффициент предпочтения (может принимать значения от 0 до 1, где 1 — означает, что более предпочтителен). Как видим типы отделяются между собой запятыми, а между типом и его коэффициентом ставится точка с запятой — application/xml;q=0.9,*/*;q=0.8 — где / — все типы. А вот там где нет значения q, он по-дефолту равен 1;

6. $_SERVER — используют для вычисления языкового предпочтения клиента(то есть возможность использования для национальной принадлежности). Извлечение идет из HTTP-заголовка Accept-Language:

Такой код может выдать такой ответ: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3. Это мои значения, у вас будут другие. Есть зависимость от браузера — англоязычные версии будут показывать в приоритете — English.


7. $_SERVER —  применяется для вычисления корневой директории сайта или папки(место, где лежит сайт, основная папка):

Такой код может показать такое: C:/Users/Sergio/OpenServer/domains/saitsozdanie.ru — если я проверяю свой сайта на локальном компьютере. На хостинге результат, естественно, будет другой, но для примера думаю красноречиво!

8. $_SERVER — используется для вычисления ip адреса клиента.

Такой код может показать такое: 127.0.0.1 это на локалке. В интернете же мы получим айпишник клиента. Если к нам на сайте человек зашел через прокси, то пользуем переменную окружения HTTP_X_FORWARDED_FOR (ее значения можно определить с помощью функции getenv() — кроме анонимных прокси, echo @getenv(HTTP_X_FORWARDED_FOR); ).

9. $_SERVER — показывает часть адреса или ссылки. К примеру, если у нас есть — http://saitsozdanie.ru/php/superglobalnyj-massiv-server-podrobno.html то элемент $_SERVER содержит это «/php/superglobalnyj-massiv-server-podrobno.html».

10. Что еще из полезного мы можем узнать из этого глобального массива:

Нетрудно догадаться и начать конструировать собственные конструкторы, которые, в принципе, уже давно созданы:

echo «http://».$_SERVER.$_SERVER; — и получить полный путь например к скрипту относительно сервера.

11. $_SERVER — позволяет получить часть ссылки после знака вопроса, то есть параметры, переданные скрипту.

12. $_SERVER — примените его и узнаете, какой метод запроса был использован GET или POST.

13. $_SERVER — для вычисления адреса скрипта относительно сервера. К примеру имеем строку запроса — http://sait.ru/byume/index.php?id=1&title=wet&them=215. Значения переменной $_SERVER — будет таковым: «/byume/index.php».

Похожее будет и с $_SERVER — этот элемент показывает абсолютный путь до файла(скрипта), только уже относительно сервера(может быть такое /var/www/sait.ru/index.php).

Более новые статьи:

  • php создание файла, чтение и запись — 22/02/2016 11:54
  • switch тонкости — 15/02/2016 13:10
  • Ошибки PHP — 05/06/2015 12:23

Перенаправление запросов для отсутствующих доменов (перенаправление по умолчанию)

Если обращение к веб-серверу идет по IP-адресу или домену, который не прописан в конфигурационном файле, можно перенаправить весь трафик на домен по умолчанию:

server {         listen 80 default_server;         return 302 https://welcome.domain.ru$request_uri; }

или независимо от протокола:

server {         listen 80 default_server;         return 302 $scheme://welcome.domain.ru$request_uri; } server {         listen 443 default_server;         return 302 $scheme://welcome.domain.ru$request_uri;         ssl on;         ssl_certificate /etc/nginx/ssl/cert.pem;         ssl_certificate_key /etc/nginx/ssl/cert.key; }

* $scheme позволяет перевести запрос на тот же протокол (http или https), по которому он был инициирован. * если nginx должен слушать и обрабатывать запросы по https, необходимо указывать в настройках пути к сертификатам.

From Inside Of An Instance/Class


Things change a bit here. The same operators are used, but their meaning becomes significantly blurred.

The object-operator is still used to make calls to the object’s instance state.

Calling the method on (an instance of ) using the object-operator: will result in the instance’s version of .

So that’s how we expect.

The meaning of the operator though changes. It depends on the context of the call to the current function:

  • Within a static context

    Within a static context, any calls made using will also be static. Let’s look at an example:

    Calling will call the method statically, and hence will not be populated. It’s worth noting that in recent versions of PHP (5.3+) this will trigger an error, because we’re calling non-static methods statically.

  • Within an instance context

    Within an instance context on the other hand, calls made using depend on the receiver of the call (the method we’re calling). If the method is defined as , then it will use a static call. If it’s not, it will forward the instance information.

    So, looking at the above code, calling will return , since the «static» call happens inside of an instance context.

Make sense? Didn’t think so. It’s confusing.

Short-Cut Keywords

Because tying everything together using class names is rather dirty, PHP provides 3 basic «shortcut» keywords to make scope resolving easier.

  • — This refers to the current class name. So is the same as within the class (any method on it).


  • — This refers to the parent of the current class.

  • — This refers to the called class. Thanks to inheritance, child classes can override methods and static properties. So calling them using instead of a class name allows us to resolve where the call came from, rather than the current level.

Examples

The easiest way to understand this is to start looking at some examples. Let’s pick a class:

Now, we’re also looking at inheritance here. Ignore for a moment that this is a bad object model, but let’s look at what happens when we play with this:

So the ID counter is shared across both instances and the children (because we’re using to access it. If we used , we could override it in a child class).

Note that we’re executing the instance method every time. But we’re using the to do it in one of the cases (the child case). This is what makes this approach powerful.

Word Of Caution #1

Note that the calling context is what determines if an instance is used. Therefore:

Is not always true.

Now it is really weird here. We’re calling a different class, but the that gets passed to the method is the instance of .

This can cause all sorts of bugs and conceptual WTF-ery. So I’d highly suggest avoiding the operator from within instance methods on anything except those three virtual «short-cut» keywords (, , and ).

Word Of Caution #2

Note that static methods and properties are shared by everyone. That makes them basically global variables. With all the same problems that come with globals. So I would be really hesitant to store information in static methods/properties unless you’re comfortable with it being truly global.

Word Of Caution #3

In general you’ll want to use what’s known as Late-Static-Binding by using instead of . But note that they are not the same thing, so saying «always use instead of is really short-sighted. Instead, stop and think about the call you want to make and think if you want child classes to be able to override that static resolved call.

Ok, fine. In short, is used to reference the current class name within a class, where as refers to the current object instance. Note that is a copy/paste short-cut. You can safely replace it with your class name, and it’ll work fine. But is a dynamic variable that can’t be determined ahead of time (and may not even be your class).


С этим читают