21
PHP/LAMP LABS Appendix General Notes.............................................................................................. 3 We’ll be using Amazon Web Services (AWS) for the labs, and we’ll be spinning up a “T1.micro” Amazon Machine Linux Instance. It’s based on RedHat, so 100% of the commands you’re used to using in RedHat Linux should work. Lab #1: Setup LAMP stack You’ll first need to create an AWS account by going to: https://console.aws.amazon.com . Although they will ask for a credit card, you should not experience any charges whatsoever on the card as our entire labs should fall well within the “free tier” status. Once you’ve created an account, browse to the EC2 instances tab at: https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#Instances : Now, follow the screenshots below to launch your instance. Choose “Launch Instance”

"PHP from soup to nuts" -- lab exercises

Embed Size (px)

Citation preview

Page 1: "PHP from soup to nuts" -- lab exercises

PHP/LAMP LABS

Appendix

General Notes.............................................................................................. 3

We’ll be using Amazon Web Services (AWS) for the labs, and we’ll be spinning up a “T1.micro” Amazon Machine Linux Instance. It’s based on RedHat, so 100% of the commands you’re used to using in RedHat Linux should work.

Lab #1: Setup LAMP stack You’ll first need to create an AWS account by going to: https://console.aws.amazon.com . Although they will ask for a credit card, you should not experience any charges whatsoever on the card as our entire labs should fall well within the “free tier” status. Once you’ve created an account, browse to the EC2 instances tab at: https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#Instances: Now, follow the screenshots below to launch your instance. Choose “Launch Instance”

Page 2: "PHP from soup to nuts" -- lab exercises

Select Amazon Linux AMI

Click “Review and Launch”

Page 3: "PHP from soup to nuts" -- lab exercises

Click “Launch”

Page 4: "PHP from soup to nuts" -- lab exercises

This is hugely important!!! Choose “Create a new key pair” & give keypair a name (phpLabKeypair is good). Then MAKE SURE TO CLICK “DOWNLOAD KEY PAIR”! IF YOU FORGET TO DO THIS, YOU WILL NOT BE ABLE TO ACCESS YOUR MACHINE & YOU’LL HAVE TO START OVER. Finally, click “Launch Instance”

Page 5: "PHP from soup to nuts" -- lab exercises

Click on the instance ID to enter the “Instances” window

Page 6: "PHP from soup to nuts" -- lab exercises

Almost there! Wait until the instance goes into “running” status, then select the whole line, expand your “detail view” & copy the “Public DNS” to your clipboard (you’ll need this to log into the instance.

Page 7: "PHP from soup to nuts" -- lab exercises

Armed with the public DNS, you can now try to login to your instance (use “ssh –i”, passing the path to the keypair you downloaded above). The first time you try to log in, you’ll get prompted to add the server to your known hosts. You’ll also get an error saying “keypair permissions too open”. Resolve per below & then try again. Your SSH session should look very similar to this. Note: Your server is using keypair auth – your username is “ec2-user”, but you’ll need to send the key with every connection request (uses no password). You’ll connect to the server the exact same way for every lab.

Please be aware!!!

At the end of every day, please do “Stop” your server in the AWS console at https://console.aws.amazon.com/ec2 . Then, every morning, “Start” your server in the AWS console. This will save your company (or yourself) any potential AWS costs. Now that you’re into your server, please follow procedures at: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/install-LAMP.html These procedures will allow you to set up all of the required components for your LAMP stack. Note: you can repeat all of these procedures again outside of class, or you can also burn an AMI of this server (after installing the stack) for later use.

Page 8: "PHP from soup to nuts" -- lab exercises

Optional Exercise: Install wordpress using procedures at http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/hosting-wordpress.html

Last Step! In the terminal of your instance, pulldown the labs code by doing the

following: cd /var/www/html/

wget http://quicloud.com/php-class/php-labs.tgz

tar –xvzf php-labs.tgz

You now have all of the lab code that we’ll be using in the class. & you are done with this exercise.

Lab #2: Control Structures Write a php program that does all of the following: * continually looks for a file in the local filesystem (the script is a long-running daemon) * if it finds the file, it outputs a message 'file is here' on a periodic basis * if the file goes missing, it outpus a message 'file has disappeared for x seconds' * the message should appear every 1 second To create the file to be checked, you can use the linux command 'touch [file]'. To delete the file to be checked, you can use the linux command 'rm -rf [file]'. Which control structure loops would you use? What other things could you check for “up” status? Extra Credit: modify your code to actually recreate the file when it’s missing, and send yourself an email when this occurs. IF YOU’RE TOTALLY LOST: the fully working solution is under “/solutions” in this lab’s directory.

Lab #3: Data Types

The code in “/labs/data-types/data-types-ugly.php” works, but man is it ugly!!! Global variables ($page), functions willy-nilly, and every time we write a new HTML page, we’ll have to use this PHP at the top. Your task, should you choose to not be embarrassed in front of everyone, is to refactor this code so that it uses a class which encapsulates the necessary PHP code in a separate class (using 3 methods – one for header, one for body, and one for footer). Once you’ve gone through a refactor, you could then use this separate class in every HTML page you want to generate, and it will create your headers, page content, footers, etc for you. Extra credit: Inside of the class you created, additionally add functions to demonstrate how we would create strings, arrays, integers, floats, NULLs, and test for each. Double extra credit: download, install, run & review the code at http://vancewalsh.com/php/ You should now be able to read & understand all of the code at http://vancewalsh.com/php/progress-class-download IF YOU’RE TOTALLY LOST: the fully working solution is under “/solutions” in this lab’s directory.

Lab #4: Input & Output Write a php program that does all of the following: Can be run as either a command line script (accept args from $argv) or as a GET param’ed Web URL.

Page 9: "PHP from soup to nuts" -- lab exercises

The script will be passed one directory in the filesystem. If the directory doesn’t exist, you need to output an error immediately to the user & exit. If the directory does exist, then you will output one line per “item” (file or directory) inside of that directory, and you need to differentiate between the two. The script will also accept two additional parameters – one for a “directory match” and one for a “file match”. For every directory, if the directory matches the optional “directory match” parameter, you’ll indicate this to the user. For every file, if the contents of the file match the “file match” parameter (one or more times), you’ll need to indicate this to the user. The ‘strstr’ function and ‘strpos’ functions will both help with finding matches. Is there any benefit to using one over the other? Some debugging hints: use ‘var_dump($variable)’ to print out what’s in a give variable NOTE: for the parameters coming into the script, it’s highly important that you validate them – check into the

‘isset’ and ‘empty’ functions. NOTE 2: try to make use of functions in this script. NOTE 3: if you need to validate two things in (say) an if conditional, you can use the ‘&&’ token, like “if(isset($param) && !empty($param)) {” Extra credit: weed out the “dot” (./ And ../) directories Double secret extra credit: use classes (if appropriate) Triple extra credit – do recursive on subdirectories IF YOU’RE TOTALLY LOST: the fuly working solution is under “/solutions” in this lab’s directory.

Lab #5: Web Forms Using basic HTML, Implement a form that can process (just receive inputs from the textboxes, checkboxes, etc) & spit back out to user, a form such as the following:

Page 10: "PHP from soup to nuts" -- lab exercises

FirstName & LastName are standard text boxes Gender is a radio button (one or the other) Food is a multi-select checkbox (user can pick multiple) Quote is a text area Education is a single-choice (user can only pick one) select box Favorite time of day is a multi-choice select box Here’s some additional constraints:

The fields are all required – if user doesn’t choose one or more of them, then the form will not submit, and you are to visually indicate to the user which fields are empty

The first time the user enters the form, it’s to appear as above, but if they submit with errors, it is to do something as shown in next graphic below

The form is to maintain all values if any are empty (eg: if user put in values for all but “first name”, then all will be maintained in the form fields (as shown below)

Page 11: "PHP from soup to nuts" -- lab exercises

Attack it in these phases:

Build the HTML form

Decide how you will accept data from the form (POST, GET) Code the PHP to enable the receipt of the data

Write code to ‘validate’ the form (ensure that all fields have at least one value). Note that the multi-select fields will actually come in as an Array in PHP.

Write code to store (maybe using arrays) if any fields failed validation, and if so, use that code to alter the HTML (for example, setting <span style=”color:red”> as I did in the example above)

If all fields validate, then create more code that simply regurgitates all the info back out to the user as shown below:

Page 12: "PHP from soup to nuts" -- lab exercises

Advanced: See if there is any way you can leverage Arrays, Variable Variables, and maybe References to make your life easier & your code more compact Super Advanced: Try to leverage an Object to manage all of this validation business. IF YOU’RE TOTALLY LOST: the fully working solution is under “/solutions” in this lab’s directory.

Lab #6: File Reading / Writing Using file access commands, write a program that simply opens another file (even itself, if you like), and displays the line number of each file as well as alternates the background text back and forth (from a light gray to white) for each line. Extra credit: also output detailed information about the file (size, permissions, full path), and write the information back out to another file in addition to sending it back out to terminal or browser.

Page 13: "PHP from soup to nuts" -- lab exercises

Extra Credit Lab: Write a completely separate piece of code that does the following: * Takes two CSV (comma separated value) files over command line * Compares the files not only line by line, but also cell-by-cell (value-by-value) * If any cells differ, output the cells that differ and exit script immediately * If all cells match, output "all match" back to user. Fully-functioning extra credit lab cod is in ‘csv-diff-extra-credit.php’ in the solutions folder

Lab #7: Cookies & Sessions This is a two part lab. In the first, we’ll focus just on cookies, in the second we’ll focus strictly on sessions. The cookies lab code will be completely distinct & separate (different, non-interacting files) from the sessions code.

Page 14: "PHP from soup to nuts" -- lab exercises

Cookies Lab: Part 1) Write a 'cookie reader' which will show the user what cookies are installed for this domain.

The code will need to: * Read all the cookies that the user has registered for this domain * display the cookies back to the user so that they can see clearly what the key & value is for each cookie * As a convenience, provide a link to the 'cookie write' code so that the user can write cookies as well Part 2) Write a 'cookie reader' which will show the user what cookies are installed for this domain.

The code will need to: * Read all the cookies that the user has registered for this domain * display the cookies back to the user so that they can see clearly what the key & value is for each cookie * As a convenience, provide a link to the 'cookie write' code so that the user can write cookies as well Once your cookie read/write code is finished, use it to test writing, reading, and deleting cookies off of your browser. If you have access to another server that runs, try putting the same code up on that server & compare the results.

Sessions Lab: Copy the code you wrote in the “Web Forms” lab into the “cookies-sessions” directory (or, alternately, you can use /labs/web-forms/solution/web-forms.php). We need to make this code login protected, which will require doing the following:

Make a modular (I’m not going to mention the C-word) bit of code that manages authentication (logins) via sessions.

Make a “login” HTML page which accepts a login username & password. For this lab, any valid email and any password of 6 characters or more will allow login (we’ll make it dynamic in the “database”

lab later). You need to provide code to validate the email and check password length.

When the user hits the “web form” page, you need to use the authentication code created above to “bounce” the user to the login page.

When the user does a successful login, “bounce” them back to whatever page they were on last. You can do this by passing the “prev_page” as a canned “GET” parameter to “login”

On the “web form” page, provide a “logout” link which, when clicked, logs the user out. An ideal way to do this would be to make that link hit the same “login” page with maybe another GET parameter like “logout=true” or something similar.

IMPORTANT: probably the very first thing you’ll want to do is set ‘session_auto_start’ to true in

/etc/php.in (and then ‘bounce’ your webserver with a “sudo service httpd restart”). Otherwise, you’ll have to start the session in either your authentication code or on every page where you want a session. If you go the route of modifying /etc/php.in (which you must edit with sudo), MAKE SURE TO MAKE A BACKUP OF IT FIRST! You can verify if sessions are on or not by browsing the “session.auto_start” parameter of php.ini (or load phpinfo()).

Questions:

Can cookies written to one domain be read by another domain?

When are cookies sent to the server?

Can I “lock” cookies down, not only by domain, but by subdomain as well? Are cookies shared from browser to browser on the same client machine?

Can you find the cookie in your browser? If so, open that cookie file & compare to what your “read/write” code says.

How do sessions work exactly? Is the session data stored on the client or on the server?

How are session_ids generated?

How can I access a user’s session_id on the server?

Where is the session_id stored on the client?

Lab #8: Date & Time

Page 15: "PHP from soup to nuts" -- lab exercises

Write some (reusable – did someone say “Objects” &/or “Classes”?) code which does the following: Provides “stopwatch” functionality which lets us benchmark other code. At the minimum, we’ll need to calculate the granular (sub-second) time when something started, and then we’ll need to be able to stop the stopwatch some time later when something finished. It may also be nice to have the number round off to a specific number of digits. Once you’ve created & tested your “Stopwatch” code, use this code to test how fast double quotes run compared to single quotes. Note that because these operations (single vs double quote string evaluation) run so fast, you’ll probably have to use a loop that runs them many, many times over in order to be able to get a meaningful value.

Lab #9: Regex Although you may not know it, every time you browsed a URL on your AWS EC2 server, your apache webserver recorded it in a logfile. Specifically, /var/log/httpd/access_log (you need to “sudo su –“ to see it). Here’s a sample of the last few lines of mine: 67.6.152.212 - - [11/Jan/2014:23:42:53 +0000] "GET /labs/cookies-sessions/solution/login.php?log_out=true HTTP/1.1" 302 437 "http://ec2-54-197-58-85.compute-1.amazonaws.com/labs/cookies-sessions/solution/sessions-web-form.php" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" 67.6.152.212 - - [11/Jan/2014:23:42:53 +0000] "GET /labs/cookies-sessions/solution/login.php?logged_out=true HTTP/1.1" 200 146 "http://ec2-54-197-58-85.compute-1.amazonaws.com/labs/cookies-sessions/solution/sessions-web-form.php" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" 67.6.152.212 - - [11/Jan/2014:23:42:55 +0000] "GET /labs/cookies-sessions/solution/sessions-web-form.php HTTP/1.1" 302 3056 "http://ec2-54-197-58-85.compute-1.amazonaws.com/labs/cookies-sessions/solution/login.php?logged_out=true" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" 67.6.152.212 - - [11/Jan/2014:23:42:55 +0000] "GET /labs/cookies-sessions/solution/login.php HTTP/1.1" 200 437 "http://ec2-54-197-58-85.compute-1.amazonaws.com/labs/cookies-sessions/solution/login.php?logged_out=true" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" 220.165.8.137 - - [12/Jan/2014:01:54:30 +0000] "HEAD / HTTP/1.0" 403 - "-" "-"

The log file has a format of Remote IP address[space]Unused[space]http login ID of user – typically unused[space]Date[space]etc.. Explained in more detail here: http://httpd.apache.org/docs/2.2/logs.html (search in page for “common log”) Write some code which :

examines this logfile, and determines for each unique page that was accessed the total # of times

that the page was accessed (you’ll want to use an array to do this).

Sort the list so that the most frequently accessed items appear at list top NOTE: Regexes are tough There may be some code lying about on the web which already provides a

regex for apache log files (this is a very common task). If you’re having a tough time trying to write a regex to match the log file, then consult “the google”.

Questions: What file did you load the most times (was that lab tough?) Do you see any accesses that you didn’t make? Where did those accesses come from? Extra credit: Count up the # of times each IP unique address hit your site. Hit your friends sites & have them hit yours, and re-run the program over & over until you see

Page 16: "PHP from soup to nuts" -- lab exercises

Lab #10: Connecting to Database Load the the “world.sql” database in /labs/connecting-to-database/solution/” into MySQL mysqladmin –uroot –p create world

mysql -uroot -p world < world_innodb.sql

NOTE: if you’re new to SQL, you may want to browse through: http://www.webstepbook.com/supplements-2ed/slides/chapter13-databases-sql.shtml#slide1 You can click the << and >> buttons (bottom right of page) to browse through the topics.

The second step may take a couple of minutes to complete. Once complete, go in & verify your database loaded. Here’s some example commands & what you should see:

Page 17: "PHP from soup to nuts" -- lab exercises

Using PDO, create a database connector (you can use another class if you like) which does all of the following:

Provides a connection to the Database

Can send queries to the database & return the results of the query back to the user

With something as important as a database connection, you probably want to use a try/catch Write a second piece of code (or just append onto existing) which uses the database class above to query the data. Knowing what you now know about web forms, you may even want to build some simple web forms to interact with this data. Some ideas:

Make a dropdown which lets user choose which table they are working with

When that dropdown is selected, create and display a second dropdown of all the fields in the table, along with a textbox to enter characters to match against for that field (eg: City LIKE ‘%AFG%’)

If you’re inclined, make your code also be able to write data back to the database (you can do this with a PDO->query, same as a select. JUST MAKE SURE you’re dealing with SQL Injection attacks. Try to attack your code & see if you can break it.

Lab #11: XML Parsing This is a two part lab with related, but distinct code (you’ll probably want to write one piece of code for each part). Part 1) In /labs/xml-parsing/solution/, you’ll find a file called “songs.xml”. This is a simple XML file which has

the contents:

Using the simpleXML parser in PHP (http://www.php.net/manual/en/book.simplexml.php), consume this file so that we output in a browser the details for every song entered in the file (dateplayed, title, and artist). Our final output should look like:

Page 18: "PHP from soup to nuts" -- lab exercises

Part 2) Now that you’ve consumed & been able to work with a local file, let’s consume a remote file. Many

(Most? All?) popular sites out there have JSON or XML based APIs to access data from their sites. In this example, we’ll consume some pictures from the popular website Flickr. If you browse to some page on Flickr (we’re using http://www.flickr.com/photos/planetoftheweb/sets/72157627229375826/ for our example), you can see something like the following (notice highlighted “Feeds”)

Page 19: "PHP from soup to nuts" -- lab exercises

Like most of Flickr (the Internet?) it is a page full of pics of cats. If you click on the feed (http://api.flickr.com/services/feeds/photoset.gne?set=72157627229375826&nsid=73845487@N00&lang=en-us ), you’ll see a whole swath of XML which looks like this:

Notice how every “Link” XML node inside of the “entry” node has an href pointing to a specific picture? Doing something similar as we had done with the local file in part #1, let’s consume this XML feed so that we display only the images back in HTML. Our final program output should look something like this:

Page 20: "PHP from soup to nuts" -- lab exercises

“The Internets is a series of tubes, clogged mainly with Kittens”

If you’re stuck, browse the PHP docs for simpleXML & get familiar with the useage. Extra Credit: Find other XML feeds on the web, and write new code to pull out, reformat, & display the interesting information back to yourself in the browser. NOTE: SimpleXML will spit error messages if you run it from command line. You must use your browser to access the PHP

Lab #12: Wrap Up

Congrats! You’ve made it this far & you now how to do all kinds of cool stuff! WooHoo! Let’s take our “Web Form” lab and hack it up a bit. Let’s make it do all of the following:

Only have some fields required (what fields make sense). Feel free to throw out / modify /add any fields you think would be useful to capture.

Capture an “email” and password, which will be our login & validate both the email and the password

Submit the info to a database (you’ll need to create a table, write a database connector class, and use that class to interact with the database). You probably DO NOT want to store the password in the clear – find an option which will be more secure.

On successful submission, drop a cookie (and update user’s session) so that the user cannot “re-enter” the info. Alternately, you can allow the users to “update” their info if they re-submit it.

Additionally, let’s make a second, password-protected PHP page. This page will: Require authentication - consult the database for the username & password entered in the Web Form

above & only allow access if both match.

On this page, also allow logout.

On successful login, display the contents of the table which stores all of our WebForm info Extra Credit: Provide some “filters” at the top of the password-protected page which allow us to limit records (maybe filter by first name match, partial email match, favorite food, etc).

Page 21: "PHP from soup to nuts" -- lab exercises

NOTE: There is no “sample code” for this exercise, but you should be able to (at the very least) Frankenstein together the sample code from previous labs. Please do reach out to your instructor and your fellow students if you’re stuck on something.