PHP & MySQL Tutorial
Cookies and Sessions I
- Setting and Getting Cookies
Before we dive into cookies, we need to look at HTTP.
HTTP is entirely oriented around the sending of client requests and server responses. These take the form of HTTP messages sent between clients and servers. As with all protocols, HTTP uses a special format that dictates the structure of both client Request messages and server Response messages. Understanding how these messages work is a big part of comprehending HTTP as a whole.
The telnet program works well as a client for our server, so we don't have to write a specialized client. Whenever we use a web browser, it makes a connection to a webserver somewhere. This connection transmits the web page over the connection using HTTP, which defines a certain way to request and send information. By default, webservers run on port 80, which is listed along with many other default ports in /etc/services.
/etc/services:
finger 79/tcp www 80/tcp http # WorldWideWeb HTTP www 80/udp # HyperText Transfer Protocol
HTTP exists in the application layer (the top layer) of the OSI model. At this layer, all of the networking details have already been taken care of by the lower layers, so HTTP uses plain text for its structure. Many other application layer protocols also use plain text, such as POP3, SMTP, IMAP, and FTP's control channel. Since these are standard protocols, they are all well documented. So, once we know the syntax of these various protocols, we can manually talk to other programs that speak the same language. For example,
GET / HTTP/1.1
will request the root document from the webserver using HTTP version 1.1. The request is actually for the root directory of /, but most webservers will automatically search for a default HTML document in that directory of index.html. If the server finds the resource, it will respond using HTTP by sending several headers before sending the content. If the command HEAD is used instead of GET, it will only return the HTTP headers without the content. These headers are plain text and can usually provide information about the server. These headers can be retrieved manualy using telnet by connecting to port 80 of a known website, then typing / HTTP/1.1 and pressing ENTER twice.
$ telnet www.google.com 80 Trying 74.125.224.80... Connected to www.l.google.com. Escape character is '^]'. HEAD / HTTP/1.1 HTTP/1.1 200 OK Date: Sun, 20 Mar 2011 22:57:14 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=ISO-8859-1 Set-Cookie: PREF=ID=1a1465e93069ef27:FF=0:TM=1300661834:LM=1300661834:S=cfgZ-CLdx3csSotG; expires=Tue, 19-Mar-2013 22:57:14 GMT; path=/; domain=.google.com Set-Cookie: NID=45=GttD9aoP3MRS7GzAw56s7soAoBm728X9cqLXCa1FIMDN0axUpk-mYHkk5p65S6E2Ms8EbechxkXpgMZw2s941LPE0aHEOgdIIcpgv4fe11uQ5PBm1DI-UfMQstisfej3; expires=Mon, 19-Sep-2011 22:57:14 GMT; path=/; domain=.google.com; HttpOnly Server: gws X-XSS-Protection: 1; mode=block Transfer-Encoding: chunked
In the output above, telnet is used to open a TCP/IP connection to the webserver at //www.google.com. Then, the HTTP application layer is manually spoken to request the headers for the main index page.
The output reveals that the webserver is gws (Google Web Server).
When we use GET, the output is:
$ telnet www.google.com 80 Trying 74.125.224.49... Connected to www.l.google.com. Escape character is '^]'. GET / HTTP/1.1 Host: www.google.com COnnection: Close HTTP/1.1 200 OK Date: Sun, 20 Mar 2011 23:14:01 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=ISO-8859-1 Set-Cookie: PREF=ID=427e2234df774edb:FF=0:TM=1300662841:LM=1300662841:S=XKgReguOX_3zRper; expires=Tue, 19-Mar-2013 23:14:01 GMT; path=/; domain=.google.com Set-Cookie: NID=45=2-G4uKrBxdo9eN1QN4sNUEh7PmtmOW7NkJG-iZcIsGKW5xswi8a6LCZgV0mSeGTMXR0-UPnR79zdQ-d8dwBCX-9HVvD4UYKtZlOIZNuFwyAOITWd2sXllTxfr0DyS8w3; expires=Mon, 19-Sep-2011 23:14:01 GMT; path=/; domain=.google.com; HttpOnly Server: gws X-XSS-Protection: 1; mode=block Connection: close <!doctype html><html><head> .... </script>Connection closed by foreign host. $
The client initiates an HTTP session by opening a TCP connection to the HTTP server with which it wishes to communicate. It then sends HTTP Request messages to the server, each of which specifies a particular type of action that the user of the HTTP client would like the server to take. Request can be generated either by specific user action such as clicking a hyperlink in a web browser. HTTP Request messages uses a format that is based on the generic message format. This format is based on the RFC 822 and MIME electronic mail message standards, although HTTP does not follow those formats precisely. Each HTTP message begines with a start line, then contains a number of message headers, followed by an empty line and optionally a message body. The body of the message may contain a resource such as a file to be communicated between client and server, called an entity.
Each Request message sent by an HTTP client to a server prompts the server to send back a Response message. Actually, in certain cases, the server may send two responses: a preliminary response, followed by the real one. Usually though, one request yields one response, which indicates the results of the server's processing of the request, and a response often also carries an entiry (file or resource) in the message body.
An HTTP Request message sent by a client to a server obviously requests that the server do something. All client/server protocols provide a way for the client to prompt the server to take action, generally by having the client give the server a series of commands. HTTP, in contrast, has methods, tather than commands. Each client Request message begins with the specification of the method that is the subject of the request.
What is the difference between a method and a command? In practical terms, nothing; they are the same. So why does HTTP use the term method instead of the command? The answer can be found in the abstract of the standard defining HTTP/1.0, RFC 1945. It states, in part, that HTTP is "a generic, stateless, object-oriented protocol which can be used for many tasks..."
Each method allows the client to specify a particular type of action to be taken by the server. Method names are always in uppercase letters. There are three methods that are commonly used in HTTP: GET, HEAD, and POST.
GET
The GET method request that server retrieve the resource specified by the URL on the HTTP request line and send it in a response back to the client. This is the most basic type of request and the one that accounts for the majority of HTTP traffic. When we enter a URL or click a link, we are usually prompting our web browser to send a GET request.
The handling of a GET request depends on a number of factors. If the URL is correct and the server can find the resource, it will send back the appropriate response to the client. If the request cannot be processed properly, an error message may result.
It's important to remember that the meaning of a GET request may change if certain headers, such as If-Modified-Since or If-Match, are used. These tell the server to send the resource only if certain conditions are met. A request of this sort is sometimes called a contitional GET. Similarly, the client may use the Range header to request that the server send it only part of a resource; this is usually used for large files. When this header is included, the request may be called a partial GET.
HEAD
The HEAD method is identical to the GET method, but it tells the server not to send the actual body of the message. Thus, the response will contain all of the headers that would have accompanied a reply to the equivalent GET message, including entiry headers describing the entity that the server would have sent had the method been GET. The client often uses this method to check the existence, status, or size of a file before deciding whether it wants the server to send the whole file.
HEAD requests are processed in the same way as GET request, except that only the headers are returned, not the actual resource.
POST
The POST method allows the client to send an entity containing arbitrary data to the server for processing. It is commonly used to enable a client to submit information such as an interactive HTML form to a program on the server, which then takes action based on that input and sends a response. This capability, is now used for all sorts of online programs. THe URL in the request specifies the name of the program on the server that is to accept the data.
Options
This method allows the client to request that the server send it information about available communication options. A URI of a resource may be specified to request information relevant to accessing that resource, or an asterisk (*) may be used to indicate that the query is about the server itself. The response includes headers that give the client more details about how the server may be accessed.
PUT
This method requests that the server store the entity enclosed in the body of the request at the URL specified in the request line. In a PUT, the URI identifies the entity in the request; thus a PUT allows a file to be copied to a server, in the exact complement to how a GET requests that a file to be copied to the client. In contrast, with a POST, the URI identifies a program intended to process the entity in the request, so it's used for interactive programs.
DELETE
This method requests that the specified resource be deleted.
TRACE
This method allows a client to receive back a copy of the request that is sent to the server, for diagnostic purposes.
As our applications become more complicated, we'll need to keep track of our users. Cookies and sessions provide the opportunity to interact with users. Sessions allow for the persistence of data, and without sessions, the web server sees each page request without the context of other page request and cannot remember data between requests.
HTTP is a stateless protocol, which means that the protocol has no built-in way of maintaining state between two transactions. So, when a user request one page, followed by another, HTTP does not offer a way for us to tell that both requests came from the same user.
Session control's main purpose is to be able to track a user during a single session on a website. If we can do this, we can support logging in a user and showing content according to personal preferences. We can track the user's behavior.
A cookie is a small piece of information that scripts can store on a client-side machine. When a browser connects to an URL, it first searches the cookies stored locally. If any of them are relevant to the URL being connected to, they will be transmitted back to the server.
Cookies are text files saved by websites on a computer accessing the sites. Each cookie can contain around 4,000 characters and up to 20 cookies can be stored for each website. The client can store a maximum of 300 cookies.
Since cookie files can be opened by any text editor, sensitive information should be encrypted. So, the user's password shouldn't be stored in a cookie. We should store a unique identification string which points to a database entry containing the password on the server.
Cookies are created with setcookie() function. To create a cookie, before any other code, tags or whitespace, the setcookie() function should be called. Though the cookie is not visible until the next page is loaded, the creation can be verified by its return value from setcookie().
<?php echo "Checking... <br />"; echo "Cookie, are you there? <br />"; if(setcookie("myFirstCookie", "myCookieData")) echo "Yes."; else echo "No."; ?> <html> <head> <title>Checking Cookie</title> </head> </html>
Answer:
The cookie is sent as an HTTP header by a web server to a web browser and then sent back unchanged by the browser each time it accesses that server.
The setcookie() function sets one cookie at a time and requires up to six arguments:
setcookie(name,value,expire,path,domain,secure)
Argument | Description |
---|---|
name | Required. Specifies the name of the cookie |
value | Required. Specifies the value of the cookie |
expire | Optional. Specifies when the cookie expires. time()+3600*24*30 will set the cookie to expire in 30 days. If this parameter is not set, the cookie will expire at the end of the session (when the browser closes). |
path | Optional. Specifies the server path of the cookie . If set to "/", the cookie will be available within the entire domain. If set to "/test/", the cookie will only be available within the test directory and all sub-directories of test. The default value is the current directory that the cookie is being set in. |
domain | Optional. Specifies the domain name of the cookie. To make the cookie available on all subdomains of example.com then you'd set it to ".example.com". Setting it to www.example.com will make the cookie only available in the www subdomain. |
secure | Optional. Specifies whether or not the cookie should only be transmitted over a secure HTTPS connection. TRUE indicates that the cookie will only be set if a secure connection exists. Default is FALSE. |
Once a cookie has been set, its value can be retrieved by referencing the cookie name in the $_COOKIE[] variable array. However, the values stored in a cookie cannot be retrieved until there is another HPPT request.
The example below shows how to store two items of data entered into form fields called "user" and "country"/ When the form is submitted, the page reloads. If values have been entered, the scripts stores these values in cookies called "firstname" and "where". The browser is then redirected to another page which retrieves the stored values from the cookies.
<?php if(isset($_POST['submit_button'])) { $user = $_POST['user']; $country = $_POST['country']; if( $user && $country ) { setcookie("firstname", $user, time()+3600); setcookie("where", $country, time()+3600); header( "Location:getcookie.php"); exit(); } } ?> <html> <head> <title>Setting Cookie</title> </head> <body> <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" > Enter your first name: <input type="text" name="user"> <br /> Enter your country: <br /> <input type="radio" name="country" value="India">India <br /> <input type="radio" name="country" value="Thailand">Thailand <br /> <input type="radio" name="country" value="Korea">South Korea <br /> <input type="radio" name="country" value="USA">USA <br /> <input type="radio" name="country" value="Netherlands">Netherlands <br /> <br /> <br /> <input type="submit" name="submit_button" value="Submit"> </form> </body> </html>
The next page gets the user's country from the cookie names "where" and puts the pages text with the name of the country.
<?php $userName = $_COOKIE['firstname']; $countryName = $_COOKIE['where']; ?> <html> <head> <title>Get Cookie Data</title> </head> <body> <p>Hello <?php echo $userName; ?>, from <?php echo " ".$countryName; ?>! </p> </form> </body> </html>
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization