CSSE 290 Web Programming
Lecture 25: Join Practice, Cookies
Reading: 14.1 - 14.4
Attribution:Except where otherwise noted, the contents of this document are
Copyright 2012 Marty Stepp, Jessica Miller, and Victoria Kirst. All rights reserved.
Any redistribution, reproduction, transmission, or storage of part
or all of the contents in any form is prohibited without the author's
expressed written permission.
Otherwise noted: Claude Anderson was given permission to modify the slides for CSSE 290 at Rose-Hulman by author Jessica Miller.
The authors' original slides, based on Web Programming Step by Step, can be seen at http://webstepbook.com.
Some of the examples in some days' slides are from David Fisher at Rose-Hulman, who was kind enough to allow me to use them.
My intention is to mark these examples with [DSF].
Practice queries
- What are the names of all teachers Bart has had?
SELECT DISTINCT t.name
FROM teachers t
JOIN courses c ON c.teacher_id = t.id
JOIN grades g ON g.course_id = c.id
JOIN students s ON s.id = g.student_id
WHERE s.name = 'Bart';
- How many total students has Ms. Krabappel taught, and what are their names?
SELECT DISTINCT s.name
FROM students s
JOIN grades g ON s.id = g.student_id
JOIN courses c ON g.course_id = c.id
JOIN teachers t ON t.id = c.teacher_id
WHERE t.name = 'Krabappel';
Designing a query
- Figure out the proper SQL queries in the following way:
- Which table(s) contain the critical data? (
FROM
)
- Which columns do I need in the result set? (
SELECT
)
- How are tables connected (
JOIN
) and values filtered (WHERE
)?
- Test on a small data set (
imdb_small
).
- Confirm on the real data set (
imdb
).
- Try out the queries first in phpMyAdmin or from the command line.
- Write the PHP code to run those same queries.
- Make sure to check for SQL errors at every step.
Example imdb
database
actors
id | first_name | last_name | gender |
433259 | William | Shatner | M |
797926 | Britney | Spears | F |
831289 | Sigourney | Weaver | F |
... |
movies
id | name | year | rank |
112290 | Fight Club | 1999 | 8.5 |
209658 | Meet the Parents | 2000 | 7 |
210511 | Memento | 2000 | 8.7 |
... |
roles
actor_id | movie_id | role |
433259 | 313398 | Capt. James T. Kirk |
433259 | 407323 | Sgt. T.J. Hooker |
797926 | 342189 | Herself |
... |
movies_genres
movie_id | genre |
209658 | Comedy |
313398 | Action |
313398 | Sci-Fi |
... |
directors
id | first_name | last_name |
24758 | David | Fincher |
66965 | Jay | Roach |
72723 | William | Shatner |
... |
movies_directors
director_id | movie_id |
24758 | 112290 |
66965 | 209658 |
72723 | 313398 |
... |
- also available,
imdb_small
with fewer records (for testing queries)
IMDb table relationships / ids
IMDb query example
[stepp@webster ~]$ mysql -u myusername -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql> use imdb_small;
Database changed
mysql> select * from actors where first_name like '%mick%';
+--------+------------+-----------+--------+
| id | first_name | last_name | gender |
+--------+------------+-----------+--------+
| 71699 | Mickey | Cantwell | M |
| 115652 | Mickey | Dee | M |
| 470693 | Mick | Theo | M |
| 716748 | Mickie | McGowan | F |
+--------+------------+-----------+--------+
4 rows in set (0.01 sec)
IMDb practice queries
- What are the names of all movies released in 1995?
- How many people played a part in the movie "Lost in Translation"?
- What are the names of all the people who played a part in the movie "Lost in Translation"?
- Who directed the movie "Fight Club"?
- How many movies has Clint Eastwood directed?
- What are the names of all movies Clint Eastwood has directed?
- What are the names of all directors who have directed at least one horror film?
- What are the names of every actor who has appeared in a movie directed by Christopher Nolan?
14.1: Cookie Basics
-
14.1: Cookie Basics
-
14.2: Programming with Cookies
-
14.3: Sessions
Stateful client/server interaction
Sites like amazon.com seem to "know who I am." How do they do this? How does a client uniquely identify itself to a server, and how does the server provide specific content to each client?
- HTTP is a stateless protocol; it simply allows a browser to request a single document from a web server
- today we'll learn about pieces of data called cookies used to work around this problem, which are used as the basis of higher-level sessions between clients and servers
What is a cookie?
- cookie: a small amount of information sent by a server to a browser, and then sent back by the browser on future page requests
- cookies have many uses:
- authentication
- user tracking
- maintaining user preferences, shopping carts, etc.
- a cookie's data consists of a single name/value pair, sent in the header of the client's HTTP GET or POST request
How cookies are sent
- when the browser requests a page, the server may send back a cookie(s) with it
- if your server has previously sent any cookies to the browser, the browser will send them back on subsequent requests
-
alternate model: client-side JavaScript code can set/get cookies
Myths about cookies
- Myths:
- Cookies are like worms/viruses and can erase data from the user's hard disk.
- Cookies are a form of spyware and can steal your personal information.
- Cookies generate popups and spam.
- Cookies are only used for advertising.
- Facts:
- Cookies are only data, not program code.
- Cookies cannot erase or read information from the user's computer.
- Cookies are usually anonymous (do not contain personal information).
- Cookies CAN be used to track your viewing habits on a particular site.
A "tracking cookie"
-
an advertising company can put a cookie on your machine when you visit one site, and see it when you visit another site that also uses that advertising company
-
therefore they can tell that the same person (you) visited both sites
-
can be thwarted by telling your browser not to accept "third-party cookies"
Where are the cookies on my computer?
- IE: HomeDirectory\Cookies
- e.g. C:\Documents and Settings\jsmith\Cookies
- each is stored as a
.txt
file similar to the site's domain name
- Chrome: C:\Users\username\AppData\Local\Google\Chrome\User Data\Default
- Firefox: HomeDirectory\.mozilla\firefox\???.default\cookies.txt
- view cookies in Firefox preferences: Privacy, Show Cookies...
How long does a cookie exist?
- session cookie : the default type; a temporary cookie that is stored only in the browser's memory
- when the browser is closed, temporary cookies will be erased
- can not be used for tracking long-term information
- safer, because no programs other than the browser can access them
- persistent cookie : one that is stored in a file on the browser's computer
- can track long-term information
- potentially less secure, because users (or programs they run) can open cookie files, see/change the cookie values, etc.
14.2: Programming with Cookies
-
14.1: Cookie Basics
-
14.2: Programming with Cookies
-
14.3: Sessions
Cookies in JavaScript
document.cookie = "username=smith";
document.cookie = "password=12345";
document.cookie = "age=29; expires=Thu, 01-Jan-1970 00:00:01 GMT";
...
var allCookies = document.cookie.split(";");
for (var i = 0; i < allCookies.length; i++) {
var eachCookie = allCookies[i].split("=");
var cookieName = eachCookie[0];
var cookieValue = eachCookie[1];
...
}
- JS has a global
document.cookie
field (a string)
-
you can manually set/get cookie data from this field (sep. by
;
), and it will be saved in the browser
-
to delete a cookie, set it to 'expire' in the past
Provided Cookie library
<script src="http://www.webstepbook.com/Cookie.js" type="text/javascript"></script>
Cookie.set("username", "smith");
alert(Cookie.get("username"));
-
we have written a Cookie.js helper class with methods
set
, get
, exists
, remove
, and remember
Setting a cookie in PHP
setcookie("name", "value");
setcookie("username", "martay");
setcookie("favoritecolor", "blue");
setcookie
causes your script to send a cookie to the user's browser
setcookie
must be called before any output statements (HTML blocks, print
, or echo
)
- you can set multiple cookies (20-50) per web domain, each up to 3-4K bytes
- technically, a cookie is just part of an HTTP header, and it could be set using PHP's
header
function (but this is less convenient, so you would not want to do this):
header("Set-Cookie: username=martay; path=/; secure");
Retrieving information from a cookie
$variable = $_COOKIE["name"];
if (isset($_COOKIE["username"])) {
$username = $_COOKIE["username"];
print("Welcome back, $username.\n");
} else {
print("Never heard of you.\n");
}
print("All cookies received:\n");
print_r($_COOKIE);
- any cookies sent by client are stored in
$_COOKIE
associative array
- use
isset
function to see whether a given cookie name exists
unset
function deletes a cookie
Setting a persistent cookie in PHP
setcookie("name", "value", timeout);
$expireTime = time() + 60*60*24*7;
setcookie("CouponNumber", "389752", $expireTime);
setcookie("CouponValue", "100.00", $expireTime);
- to set a persistent cookie, pass a third parameter for its timeout in seconds
time
function returns the current time in seconds
date
function can convert a time in seconds to a readable date
Removing a persistent cookie
setcookie("name", "", time() - 1);
setcookie("CouponNumber", "", time() - 1);
- if the server wants to remove a persistent cookie, it should set it again, passing a timeout that is prior to the present time
14.3: Sessions
-
14.1: Cookie Basics
-
14.2: Programming with Cookies
-
14.3: Sessions
What is a session?
- session: an abstract concept to represent a series of HTTP requests and responses between a specific Web browser and server
- HTTP doesn't support the notion of a session, but PHP does
- sessions vs. cookies:
- a cookie is data stored on the client
- a session's data is stored on the server (only 1 session per client)
- sessions are often built on top of cookies:
- the only data the client stores is a cookie holding a unique session ID
- on each page request, the client sends its session ID cookie, and the server uses this to find and retrieve the client's session data
How sessions are established
- client's browser makes an initial request to the server
- server notes client's IP address/browser, stores some local session data, and sends a session ID back to client
- client sends that same session ID back to server on future requests
- server uses session ID to retrieve the data for the client's session later, like a ticket given at a coat-check room
Sessions in PHP: session_start
session_start();
session_start
signifies your script wants a session with the user
- must be called at the top of your script, before any HTML output is produced
- when you call
session_start
:
- if the server hasn't seen this user before, a new session is created
- otherwise, existing session data is loaded into
$_SESSION
associative array
- you can store data in
$_SESSION
and retrieve it on future pages
- complete list of PHP session functions
Accessing session data
$_SESSION["name"] = value;
$variable = $_SESSION["name"];
if (isset($_SESSION["name"])) {
if (isset($_SESSION["points"])) {
$points = $_SESSION["points"];
print("You've earned $points points.\n");
} else {
$_SESSION["points"] = 0;
}
- the
$_SESSION
associative array reads/stores all session data
- use
isset
function to see whether a given value is in the session
Where is session data stored?
- on the client, the session ID is stored as a cookie with the name
PHPSESSID
- on the server, session data are stored as temporary files such as
/tmp/sess_fcc17f071...
- you can find out (or change) the folder where session data is saved using the
session_save_path
function
- for very large applications, session data can be stored into a SQL database (or other destination) instead using the
session_set_save_handler
function
Session timeout
- because HTTP is stateless, it is hard for the server to know when a user has finished a session
- ideally, user explicitly logs out, but many users don't
- client deletes session cookies when browser closes
- server automatically cleans up old sessions after a period of time
- old session data consumes resources and may present a security risk
- adjustable in PHP server settings or with
session_cache_expire
function
- you can explicitly delete a session by calling
session_destroy
Browsers that don't support cookies
session_start();
$orderUrl = "/order.php?PHPSESSID=" . session_id();
- if a client's browser doesn't support cookies, it can still send a session ID as a query string parameter named
PHPSESSID
- this is done automatically;
session_start
detects whether the browser supports cookies and chooses the right method
- if necessary (such as to build a URL for a link on the page), the server can find out the client's session ID by calling the
session_id
function
Ending a session
session_destroy();
Implementing user logins
- many sites have the ability to create accounts and log in users
- most apps have a database of user accounts
- when you try to log in, your name/pw are compared to those in the database
Example simpsons
database
students
id | name | email | password |
123 | Bart | bart@fox.com | bartman |
456 | Milhouse | milhouse@fox.com | fallout |
888 | Lisa | lisa@fox.com | vegan |
404 | Ralph | ralph@fox.com | catfood |
|
teachers
id | name |
1234 | Krabappel |
5678 | Hoover |
9012 | Stepp |
|
courses
id | name | teacher_id |
10001 | Computer Science 142 | 1234 |
10002 | Computer Science 143 | 5678 |
10003 | Computer Science 190M | 9012 |
10004 | Informatics 100 | 1234 |
|
grades
student_id | course_id | grade |
123 | 10001 | B- |
123 | 10002 | C |
456 | 10001 | B+ |
888 | 10002 | A+ |
888 | 10003 | A+ |
404 | 10004 | D+ |
|
- You should have used phpmyadmin to load this small database on your machine
Exercise: Simpsons grade display
- Write a site where Springfield Elementary students can log in to check their grades.
- Implement a user login system that verifies proper user names and passwords.
- A student should only be able to view his/her own grades.
- We will begin tis todayand finish it tomorrow
"Remember Me" feature
- How might an app implement a "Remember Me" feature, where the user's login info is remembered and reused when the user comes back later?
- Is this stored as session data? Why or why not?
- What concerns come up when trying to remember data about the user who has logged in?