diving into php
DESCRIPTION
Course lecture for Fast, Easy, Complicated, and Powerful Webhttp://fecpw.phiffer.org/TRANSCRIPT
![Page 1: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/1.jpg)
Diving into PHPFast, Easy, Complicated, and Powerful Web
ITP, Spring 2011, section 1, session 1Dan Phiffer [email protected]
![Page 2: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/2.jpg)
Diving into PHP
![Page 3: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/3.jpg)
A simple content management system
1. Build a form for user input
2. Store submissions in a database
3. Retrieve submission data
![Page 4: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/4.jpg)
<form action="basic-form.php"> <input type="text" name="query" /> <input type="submit" name="button" value="Kablooey" /></form>
Basic form
![Page 5: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/5.jpg)
<?php echo $_REQUEST["query"]; ?><form action="basic-form.php"> <input type="text" name="query" /> <input type="submit" name="button" value="Kablooey" /></form>
Feedback
![Page 6: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/6.jpg)
<?php echo $_REQUEST["query"]; ?><form action="basic-form.php"> <input type="text" name="query" /> <input type="submit" name="button" value="Kablooey" /></form>
Feedback
![Page 7: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/7.jpg)
<?php echo $_REQUEST["query"]; ?><form action="basic-form.php"> <input type="text" name="query" /> <input type="submit" name="button" value="Kablooey" /></form>
What’s that ‘notice’ about?
![Page 8: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/8.jpg)
<?phpif (isset($_REQUEST["query"])) { echo $_REQUEST["query"];}?><form action="basic-form.php"> <input type="text" name="query" /> <input type="submit" name="button" value="Kablooey" /></form>
Solution: check if it’s set
![Page 9: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/9.jpg)
<?phpif (isset($_REQUEST['query'])) { echo "<h1>You wrote: '{$_REQUEST['query']}'</h1>";}?><form action="basic-form.php"> <input type="text" name="query" /> <input type="submit" name="button" value="Kablooey" /></form>
Dynamic strings
![Page 10: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/10.jpg)
Try it out
![Page 11: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/11.jpg)
<?php$query = "";if (isset($_REQUEST["query"])) { $query = $_REQUEST["query"]; echo "<h1>You wrote: '$query'</h1>";}?><form action="basic-form.php" > <input type="text" name="query" value="<?php echo $query; ?>" /> <input type="submit" name="button" value="Kablooey" /></form>
Defining a new variable
![Page 12: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/12.jpg)
Step 1 complete!
![Page 13: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/13.jpg)
Wait, this is bad
![Page 14: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/14.jpg)
User types input...
![Page 15: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/15.jpg)
Clicks away... arbitrary JavaScript execution!
![Page 16: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/16.jpg)
We’ve been tricked into adding an ‘onblur’ attribute!
![Page 17: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/17.jpg)
Cross-site scripting (XSS)
• A common security vulnerability
• When content is unintentionally executed as code
• We must handle user-submitted content very carefully
![Page 18: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/18.jpg)
Dangers of XSS
• Users’ sessions could be hijacked
• Passwords could be stolen
• Your site could get spammed up
• Puppies murdered, etc.
![Page 19: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/19.jpg)
<?php$query = "";if (isset($_REQUEST["query"])) { // htmlentities() turns " into " $query = htmlentities($_REQUEST["query"]); echo "<h1>You wrote: '$query'</h1>";}?><form action="basic-form.php" > <input type="text" name="query" value="<?php echo $query; ?>" /> <input type="submit" name="button" value="Kablooey" /></form>
Escaping user input
![Page 20: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/20.jpg)
Before & after escaping
![Page 21: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/21.jpg)
Now we’re really finished with step 1
1. Build a form for user input
2. Store submissions in a database
3. Retrieve submission data
![Page 22: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/22.jpg)
Adding a database
![Page 23: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/23.jpg)
Relational databases
• Tables with columns and rows of individual data cells
• SQL is the language for working with relational databases
• MySQL is the database platform used by WordPress
![Page 24: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/24.jpg)
The four operations
• Create new rows with INSERT
• Read rows with SELECT
• Update rows with UPDATE
• Delete rows with DELETE
• MySQL documentation
![Page 25: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/25.jpg)
MySQL clients
• Sequel Pro (Mac OS X)
• SQLWave, SQLMaestro (Windows)
• phpMyAdmin (web-based)
• Or from the command-line: ‘mysql’
![Page 26: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/26.jpg)
$ mysql -u root
![Page 27: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/27.jpg)
mysql> CREATE DATABASE
![Page 28: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/28.jpg)
-> tinydb CHARACTER SET utf8;
![Page 29: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/29.jpg)
mysql> USE tinydb;
![Page 30: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/30.jpg)
mysql> CREATE TABLE tinytable
![Page 31: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/31.jpg)
-> (id INTEGER PRIMARY KEY AUTO_INCREMENT);
![Page 32: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/32.jpg)
![Page 33: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/33.jpg)
mysql> ALTER TABLE tinytable ADD COLUMN
![Page 34: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/34.jpg)
-> content TEXT;
![Page 35: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/35.jpg)
![Page 36: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/36.jpg)
![Page 37: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/37.jpg)
mysql> INSERT INTO tinytable
![Page 38: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/38.jpg)
-> (id, content)
![Page 39: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/39.jpg)
-> VALUES (1, 'Hello, world!');
![Page 40: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/40.jpg)
mysql> SELECT * FROM tinytable;
![Page 41: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/41.jpg)
Let’s build a tiny wiki!
![Page 42: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/42.jpg)
A simple content management system
1. Build a form for user input
2. Store submissions in a database
3. Retrieve submission data
![Page 43: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/43.jpg)
A simple content management system
1. Build a form for user input
2. Store submissions in a database
3. Retrieve submission data
![Page 44: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/44.jpg)
<!DOCTYPE html><html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <title>Tiny wiki</title> </head> <body> <?php $content = ""; // We need to load the content! ?> <form action="tiny-wiki.php" method="post"> <input type="text" name="content" value="<?php echo $content; ?>" /> <input type="submit" value="Update" /> </form> </body></html>
Basic form
![Page 45: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/45.jpg)
<?php
$content = load_content();
function load_content() { // Load content from the database return "";}
?>
Add a load function
![Page 46: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/46.jpg)
<?php
$db = connect_to_database();$content = load_content($db);
function load_content($db) { // Load content from the database return "";}
function connect_to_database() { // Connect to the database}
?>
Add a database function
![Page 47: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/47.jpg)
function connect_to_database() { $host = "127.0.0.1"; $port = 8889; $user = "root"; $pass = "root"; $name = "tinydb"; $dsn = "mysql:host=$host;port=$port;dbname=$name"; return new PDO($dsn, $user, $pass);}
Connecting to the database
![Page 48: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/48.jpg)
function load_content($db) { $sql = "SELECT * FROM tinytable ORDER BY id DESC"; $query = $db->query($sql); $results = $query->fetchAll(); $row = $results[0]; return $row["content"];}
Querying the database
![Page 49: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/49.jpg)
<?php
$db = connect_to_database();$content = load_content($db);
function load_content($db) { $sql = "SELECT * FROM tinytable ORDER BY id DESC"; $query = $db->query($sql); $results = $query->fetchAll(); $row = $results[0]; return $row['content'];}
function connect_to_database() { $host = "127.0.0.1"; $port = 8889; $user = "root"; $pass = "root"; $name = "tinydb"; $dsn = "mysql:host=$host;port=$port;dbname=$name"; return new PDO($dsn, $user, $pass);}
?><form action="tiny-wiki.php" method="post"> <input type="text" name="content" value="<?php echo $content; ?>" /> <input type="submit" value="Update" /></form>
tiny-wiki.php
![Page 50: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/50.jpg)
Result
![Page 51: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/51.jpg)
A simple content management system
1. Build a form for user input
2. Store submissions in a database
3. Retrieve submission data
![Page 52: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/52.jpg)
<?php
$db = connect_to_database();$content = load_content($db);
if (!empty($_REQUEST["content"])) { save_content($db, $_REQUEST["content"]); $content = htmlentities($_REQUEST["content"]);}
?>
Core logic
![Page 53: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/53.jpg)
function save_content($content) { $sql = "INSERT INTO tinytable (content) VALUES ('$content')"; $db->query($sql);}
Saving the content
![Page 54: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/54.jpg)
Save the content
![Page 55: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/55.jpg)
A simple content management system
1. Build a form for user input
2. Store submissions in a database
3. Retrieve submission data
![Page 56: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/56.jpg)
Wait, this is bad
![Page 57: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/57.jpg)
$content = "'); drop table tinytable; --";$sql = "INSERT INTO tinytable (content) VALUES ('$content')";
How does it work?
![Page 58: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/58.jpg)
$content = "'); drop table tinytable; --";$sql = "INSERT INTO tinytable (content) VALUES ('$content')";
// Result: (-- is a comment in SQL)// "INSERT INTO tinytable (content)// VALUES (''); drop table tinytable; --')
How does it work?
![Page 59: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/59.jpg)
SQL injection
• Another security vulnerability, similar to cross site scripting
• When user data is unintentionally executed as SQL
• Escaping works here also (also, prepared statements)
![Page 60: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/60.jpg)
function save_content($db, $content) { $content = $db->quote($content); $sql = "INSERT INTO tinytable (content) VALUES ($content)"; // no more single quotes $db->query($sql, array($content));}
Escape the user input
![Page 61: Diving into php](https://reader033.vdocuments.us/reader033/viewer/2022052900/555cf864d8b42add648b4f8f/html5/thumbnails/61.jpg)
Done!
• Download the files
• Try running the tiny wiki on your own local Apache/MySQL/PHP
• Get familiar with the PHP manual