URI, $link->title); $link = rid2link(140); $HTTP = anchor($link->URI, 'HTTP/1.1', $link->title); $request = implode(' ', array($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI'], $_SERVER['SERVER_PROTOCOL'])); $link = rid2link(131); $Apache = anchor($link->URI, 'Apache', $link->title); $request_line = anchor('http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1', 'Request-Line', 'HTTP/1.1 ' . $ent['sect'] . ' 5.1 Request-Line'); $GET = anchor('http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3', 'GET', 'HTTP/1.1 ' . $ent['sect'] . ' 9.3 GET'); $POST = anchor('http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5', 'POST', 'HTTP/1.1 ' . $ent['sect'] . ' 9.5 POST'); $method = anchor('http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.1', 'method', 'HTTP/1.1 ' . $ent['sect'] . ' 5.1.1 Method'); $subdomain = anchor(wiki_uri('Subdomain'), 'subdomain', 'Subdomain'); $status_line = anchor('http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1', 'Status-Line', 'HTTP/1.1 ' . $ent['sect'] . ' 6.1 Status-Line'); $status_code = anchor('http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1', 'status code', 'HTTP/1.1 ' . $ent['sect'] . ' 6.1.1 Status Code and Reason Phrase'); $link = cid2link(57); $Media_types = anchor($link->URI, 'Media Types', $link->title); $link = rid2link(136); $MIME_types = anchor($link->URI, 'MIME Media Types', $link->title); $link = rid2link(138); $XHTML_Media_types = anchor($link->URI, 'XHTML Media Types', $link->title); $header = anchor('http://www.php.net/manual/function.header.php', 'header()', 'PHP header() function'); $html = tag('html'); $link = rid2link(1024); $LiveHTTPHeaders = anchor($link->URI, $link->title); $link = cid2link(32); $Firefox = anchor($link->URI, 'Firefox', 'drx: ' . $link->title); $ieHTTPHeaders = anchor('http://www.blunck.info/iehttpheaders.html', 'ieHTTPHeaders'); $metaDataInURI = 'http://www.w3.org/2001/tag/doc/metaDataInURI-31#erroneous'; $common_mistake = anchor($metaDataInURI, 'common mistake', 'W3C: The use of Metadata in URIs ' . $ent['sect'] . ' 2.1 Reliability of URI metadata'); $Authority_and_Path_Components = <<<_Q is to make inferences based on the last segment in the path component of a URI. For example, it is common to assume that a URI with a path that ends in ${q}.html${_q} identifies an HTML document. _Q; $a_common_mistake = quote('a ' . $common_mistake . $Authority_and_Path_Components, $metaDataInURI); // PHP lab navigation $nav = labnav($did); $N = 16; // DOCTYPE $laquo = '' . $ent['laquo'] . ''; $prev = anchor($nav['path'], 'Prev', $nav['index'], null, 'prev'); $next = anchor($nav['path'] . key($nav[$N]), 'Next', $nav[$N][key($nav[$N])], null, 'next'); $raquo = '' . $ent['raquo'] . ''; $thispage = $nav[$fid][key($nav[$fid])]; echo <<<_C
Protocol

${Q}a convention or standard that controls or enables the connection, communication, and data transfer between two computing endpoints.${_Q}

$protocol

Contents

  1. Introduction to HTTP
  2. The doctype() Function
  3. PHP Labs Navigation

Important: If you missed the introduction to this PHP lab series and what follows confuses you then I recommend you take a step back and $read_it.

A Brief Introduction to HTTP

How does your browser fetch a resource on the Web and know what to do with it?

${abbr['HTTP']} is the protocol that drives the ${abbr['WWW']}. It was conceived by Sir $tim_lee (that${ent['rsquo']}s right, they $knighted him). The Web is based on the $client_server programming model in which the client (your browser) requests a resource (a Web page) from a server. A brief negotiation is made and the server returns the resource after which the browser renders the page and then you can view (or perhaps listen) to it. While all of that may seem complex and time consuming, HTTP is designed to be simple, and more importantly, very fast. This is one of the primary reasons the Web has been so successful.

If any of this is new to you, I cannot recommend highly enough this ${abbr['W3C']} document: $TAG.

Each $HTTP transaction consists of a set of one line $headers, starting with a request from the client:

$request Host: ${_SERVER['HTTP_HOST']} User-Agent: ${_SERVER['HTTP_USER_AGENT']} Accept: ${_SERVER['HTTP_ACCEPT']} ...

Something to keep in mind is that these are not an arbitrary examples, the headers came directly from the request you made when you visited this page. Since ${abbr['PHP']} is installed as an extension module into my Web server software, which happens to be $Apache (an open-source Web server, and by far the most popular one on the Internet), I have full access to the ${abbr['SAPI']}, meaning I can easily retrieve information about the request, and am able to return all sorts of interesting things in the response.

To break down the example, the first line is the resource you were interested in and is referred to, naturally, as the $request_line:

  1. $GET ${ent['mdash']} the request $method ($POST is used for submitting forms)
  2. ${_SERVER['REQUEST_URI']} ${ent['mdash']} the ${abbr['URL']} of the resource
  3. ${_SERVER['SERVER_PROTOCOL']} ${ent['mdash']} the protocol and version number

The other HTTP request headers include:

  1. Host: the domain and $subdomain (www for example)
  2. User-Agent: a string that identifies your browser
  3. Accept: a list of media (${Q}${abbr['MIME']}${_Q}) types the client understands

FAQ: What are $Media_types? In particular, review the ${abbr['IANA']} $MIME_types and the W3C $XHTML_Media_types.

There are of course other headers, but we won${ent['rsquo']}t get into that. The server responds:

${_SERVER['SERVER_PROTOCOL']} 200 OK Server: ${_SERVER['SERVER_SOFTWARE']} Content-type: $media_type; charset=$charset ...

Once again, these are not contrived examples but originated with the negotiation between my HTTP server and your browser when you requested this document. The $status_line is another ordered set:

  1. ${_SERVER['SERVER_PROTOCOL']} ${ent['mdash']} the protocol and version number
  2. 200 ${ent['mdash']} the status code, and in readable form (reason phrase):
  3. OK ${ent['mdash']} in this case everything is fine, the document follows

Note: The $status_code might interest you if you${ent['rsquo']}ve ever requested a document that either doesn${ent['rsquo']}t exist or was removed. This is the infamous 404 ${Q}Not Found${_Q} page. HTTP/1.1 status codes are grouped into ranges ${ent['mdash']} the 400 and 500 ranges are reserved for error conditions.

The other HTTP response headers include:

  1. Server: a string that identifies my server
  2. Content-type: the media type of the document I am sending

Notice that Content-type also includes the encoding (UTF-8) used for special characters. What interests us for this lab are the Accept (request) and Content-type (response) headers. Normally the server will automatically send the content type based on the extension of the file being requested ${ent['mdash']} typically .html ${ent['mdash']} which translates into the media type text/html. But if we want to serve our documents as XHTML we${ent['rsquo']}ll have to override this default behavior. To do this we${ent['rsquo']}ll be using the PHP $header function. You could of course serve static XHTML files as .xhtml, assuming your Web server is configured to do this, but we${ent['rsquo']}re discussing dynamic PHP documents here.

Note: However, $a_common_mistake

In plain English: What a URI appears to be and what it actually is may be two very different things.

FYI: If this is new to you I should point out that the HTTP headers that make up the transaction between client and server are not normally visible to you. If this interests you, and you${ent['rsquo']}d like to see more examples then I suggest you try a modern Mozilla-based browser such as $Firefox (if you haven${ent['rsquo']}t already). An excellent extension is available called $LiveHTTPHeaders that will allow you to see every header exchanged between the client and the server for any request you make. You can install a similar plug-in for ${abbr['IE']} called $ieHTTPHeaders.

The doctype() Function

In the next lab we will put all of this together into my PHP doctype() function. It actually does quite a bit more that just send the ${abbr['DTD']} declaration. Depending on the browser requesting the page, it will:

  1. Send the correct Content-type header in the HTTP response.
  2. Return the ${abbr['XML']} declaration.
  3. Print one of the seven DOCTYPEs depending on how you called it.
  4. Open the top level (root) element with the $html tag.
_C; updated(); footer(); // vnav/labs/PHP/HTTP.php ?>