Dive into the dynamics of PHP and MySQL in this comprehensive tutorial, covering everything from basics like form submission and working with different fields, to ensuring page security from cross-site scripting attacks.
This exercise is excerpted from Noble Desktop’s past app development training materials and is compatible with iOS updates through 2021. To learn current skills in web development, check out our coding bootcamps in NYC and live online.
Topics covered in this PHP & MySQL tutorial:
Post vs. get, Radios, checkboxes, & select fields, Magic quotes, Securing the page, Using functions
Exercise Overview
In this exercise, we’ll cover the basics of PHP form submission. We’ll explore the difference between POST and GET, how to deal with radio, checkbox, and select fields, and how to secure your pages from XSS (cross-site scripting) attacks.
Setting Up a Basic Form
-
In your code editor, open form.php from the form-basic folder in the phpclass folder.
This is a simple signup page that we need to prepare to use with PHP.
-
Around line 13 find the
<form>
tag:<form action="" method="get" name="signup" id="signup">
Notice that the action is currently blank and the method is set to get. There are two method options: get and post. Get will put all of your form data into the URL and Post will put the data behind the scenes. We’ll explore the differences between the two shortly.
-
First let’s link the form to the action page. We’ve already started a basic action page called form-action.php. In the
<form>
tag, change the action to point to the new page, as shown in bold below:<form action="form-action.php" method="get" name="signup" id="signup">
Save the file.
-
Now let’s add some code on our action page that will display the contents of the form. When you submit a form to PHP with the get method the values are stored in an array called
$_GET
.To access a specific field, such as email, you’d use:
$_GET['email']
If you submitted a form with post, PHP puts everything into the
$_POST
array. In that case, to access a specific field such as email, you’d use:$_POST['email']
Open form-action.php from the form-basic folder in the phpclass folder.
-
For now let’s just display the entire
$_GET
array. Under the opening<body>
tag add the following bold code:<?php print_r($_GET); ?>
-
Save the page and then in a browser go to:
- Mac: localhost:8888/phpclass/form-basic/form.php
- Windows: localhost/phpclass/form-basic/form.php
NOTE: We are previewing form.php, the file with our form. This is not the form-action.php file we just edited.
Fill out the form and submit it.
-
On the action page, you’ll see something like:
Array ( [name] => Jeremy Kay [email] => jeremy@jeremy.com [level] => expert [publications] => Elle [howoftentrack] => daily [comments] => This form is great! [submit] => Sign Me Up! )
-
Look at the URL of the page, and you’ll see that all of the contents of the form are there as well:
http://localhost:8888/phpclass/form-basic/form-action.php?name=Jeremy+Kay&email=jeremy%40jeremy.com&level=expert&publications=Daily+Racing+Form&publications=Elle&howoftentrack=daily&comments=This+form+is+great!&submit=Sign+Me+Up!
Whew, that’s a mess. If we format it a bit more legibly, it looks like:
http://localhost:8888/phpclass/form-basic/form-action.php ?name=Jeremy+Kay &email=jeremy%40jeremy.com &level=expert &publications=Daily+Racing+Form &publications=Elle &howoftentrack=daily &comments=This+form+is+great%21 &submit=Sign+Me+Up%21
Notice that the first portion is the URL of the server and page. The form portion is put after the ? and each form field begins with a & followed by the name of the field. URLs cannot contain spaces or special characters so it is automatically URL encoded for us (notice all the spaces have become + signs).
Post vs. Get
While the get method has its uses, it also has its drawbacks. First, it is obviously less secure because a user can see and manipulate the data however they want. Second, because the whole form is put into the URL, there are length limits. If you had a lot of fields or a very long comments section, it might get cut off because browsers put a limit on how long a URL can be. For these reasons, it’s better to use post when submitting forms.
Switch back to your code editor.
-
Switch to form.php and change the method to post as shown in bold:
<form action="form-action.php" method="post" name="signup" id="signup">
Save the page.
Switch to form-action.php.
Let’s display each form field individually. Delete the
print_r()
code and its surrounding php tags.-
Then, next to the Name and Email add the following bold code:
<p><strong>Name:</strong> <?php echo $_POST['name']; ?></p> <p><strong>Email:</strong> <?php echo $_POST['email']; ?></p>
-
Save the page and then in a browser go to:
- Mac: localhost:8888/phpclass/form-basic/form.php
- Windows: localhost/phpclass/form-basic/form.php
Fill out the form and submit it. You’ll see the name and email displayed. Excellent.
Radios, Checkboxes, & Select Fields
Working with radios, checkboxes, and select fields requires special care. First, if the checkbox or radio is not selected by the user, then the form does not send the input at all. What this means is that we have to check to see if the form field exists before we start to process it. Second, if they accept more than one input, such as a range of checkboxes, they must be sent to PHP as an array. Because it is sent as an array, we then need to process that form element differently.
First we need to set up the checkbox fields to be properly named for PHP. Any input that accepts multiple values must have brackets added after its name for PHP to properly process all the values. For example if a radio field is named publications you must change the name to publications[ ] to work with PHP. Be sure you change the name of the input and not the id.
Switch back to your code editor.
Switch to form.php.
-
Find the What do you read? checkbox fields around line 31. Add brackets to the name as shown in bold below:
<label><input name="publications[]" type="checkbox" id="publications_drf" value="Daily Racing Form"> Daily Racing Form</label> <label><input name="publications[]" type="checkbox" id="publications_elle" value="Elle"> Elle</label>
Save the page.
Switch to form-action.php.
-
Around line 11, find Level and add php tags as shown below (add them between the p tags):
<p><strong>Level:</strong> <?php ?> </p>
-
First we must check to see if the level form element has been set. Add the following bold code:
<p><strong>Level:</strong> <?php if ( isset($_POST['level']) ) { } ?> </p>
We must check if the level element is set in case the user does not select a radio option. If we didn’t check this PHP would error out.
-
Now output the level. Add the following bold code:
<p><strong>Level:</strong> <?php if ( isset($_POST['level']) ) { echo $_POST['level']; } ?> </p>
-
Next let’s take care of the publications checkbox. Around line 18 find Publications and add php tags as shown below (add them between the p tags):
<p><strong>Publications:</strong> <?php ?> </p>
-
Add an if statement that checks to see if the publications checkbox has been checked. If we didn’t write this if statement and the user did not check the checkbox, PHP would give an error. Add the following bold code:
<p><strong>Publications:</strong> <?php if ( isset($_POST['publications']) ) { } ?> </p>
-
Because publications is an array, we have to process it in a special way (remember we added [] brackets after the name which makes it an array). An easy way to deal with the array is to simply turn it into a comma-delimited list. To do that, we can use the
implode()
function which, although not as exciting to watch as its name might have you believe, is quite useful in this case. Add the following bold code:<p><strong>Publications:</strong> <?php if ( isset($_POST['publications']) ) { echo implode(', ', $_POST['publications']); } ?> </p>
This says to turn the publications array into a list. implode() takes two parameters, the first of which is the delimiter. In our case we want a comma-delimited list followed by a space. The second parameter is the array variable we want to implode.
-
The next two fields are easy, as we can just output the strings to the page. Find the How often track paragraph and add the following bold code:
<p><strong>How often track:</strong> <?php echo $_POST['howoftentrack']; ?></p>
-
For the Comments paragraph, we’ll output the variable in a separate paragraph tag to make it a bit neater. Add the bold code below the Comments paragraph:
<p><strong>Comments:</strong></p> <p><?php echo $_POST['comments']; ?></p>
-
Save the page and then in a browser go to:
- Mac: localhost:8888/phpclass/form-basic/form.php
- Windows: localhost/phpclass/form-basic/form.php
Fill out the form and test everything out. Everything should be outputting nicely.
-
Go back and fill out the form again, except this time in the Comments field, be sure to add a few line breaks such as:
This is a great form!
And the comments field is spectacular. Submit the form and notice that the line breaks were not preserved. There is a function called
nl2br()
that will take care of this for us.Switch back to your code editor. You should still be in form-action.php.
-
Wrap the
nl2br()
function around the comments post echo as shown in bold:<p><strong>Comments:</strong></p> <p><?php echo nl2br($_POST['comments']); ?></p>
Don’t forget the closing parenthesis!
-
Save the page and then in a browser go to:
- Mac: localhost:8888/phpclass/form-basic/form.php
- Windows: localhost/phpclass/form-basic/form.php
Fill out the form and test out the comments field. The line breaks will now be preserved.
Magic Quotes
Magic Quotes are an old PHP security feature designed to help prevent injection attacks when querying a database. They work by automatically adding a backslash in front of every quote. Unfortunately this does not adequately protect the database, and has the annoying side effect of adding a bunch of slashes to your text! Because of this, Magic Quotes have been deprecated in newer versions of PHP. However, many ISPs still have Magic Quotes set to on. It is best practice to turn them off before developing your application.
Magic Quotes in Action
-
In a browser go to:
- Mac: localhost:8888/phpclass/form-basic/form.php
- Windows: localhost/phpclass/form-basic/form.php
For the name enter: Peter O’Toole.
Submit the form.
-
If magic quotes are turned on, it will be output as: Peter O\’Toole
If there is no backslash, then you are using a newer version of PHP or Magic Quotes have been turned off and you can skip over the next section and continue with the Securing the Page section.
How to Tell if Magic Quotes Are On
Open test-magic-quotes.php from the phpclass folder.
-
Notice the first line of code reads:
<?php phpinfo(); ?>
phpinfo() is a function that displays all the info for your current PHP installation. You can also run this function on your remote server to find out more about what features your ISP has turned on and off.
-
Let’s see this function in action. In a browser go to:
- Mac: localhost:8888/phpclass/test-magic-quotes.php
- Windows: localhost/phpclass/test-magic-quotes.php
-
Press Cmd–F (Mac) or Ctrl–F (Windows) and search for magic_quotes_gpc
NOTE: If you can’t find it on the page, then you are using a newer version of PHP where magic quotes have been deprecated.
Ideally, it will be set to Off. XAMPP by default has the feature turned off, however by default MAMP (if running an older version of PHP) has them turned on. If you’re using XAMPP, you can skip to the next section.
Switch to MAMP Pro.
Click the PHP tab.
Under PHP Version, choose PHP 5.6.x. (We’d like to use the latest version, but you should check to see what version your ISP is running before developing your app. If your ISP is still running 5.2 then you should use that.)
Go to File > Edit Template > PHP > PHP 5.6.x php.ini.
If you get a warning, just click OK.
Scroll down to around line 381.
-
Add the following bold code:
magic_quotes_gpc = Off
Close the window and save when asked.
Hit the Stop button.
Hit the Start button.
Go back to your browser and reload the
phpinfo()
page.Search for magic_quotes_gpc. You’ll see that it is now Off.
Securing the Page
We’ve learned the basics of form submission, however there is one giant problem: the page we have now is totally insecure. As a rule you should NEVER display any user input on the page directly without first sanitizing it. For example, a malicious user could insert any sort of JavaScript or HTML that could actually be run on the page.
Let’s see what might happen if we do not first sanitize user input.
-
In a browser go to:
- Mac: localhost:8888/phpclass/form-basic/form.php
- Windows: localhost/phpclass/form-basic/form.php
-
In the Name field, enter the following:
<i>Your Name</i>
-
Submit the form. You’ll see that your name has been italicized.
While this may not seem serious, an informed attacker could potentially wreak havoc on your site by running any JavaScript or HTML they desire.
There are a number of different ways to filter user input. You can choose to strip out all HTML characters so
<i>Your Name</i>
would become Your Name. Because we are outputting to an HTML page, the safest way to is automatically escape any HTML characters. We do this using thehtmlentities()
function.htmlentities()
will take<i>
and convert it to:<i>
This way the browser does not render it as HTML (and will not run any script tags), but will display exactly as the user entered it.
Switch back to your code editor.
Switch to form-action.php.
-
We are going to build a function to sanitize the input. At the very top of the document, above the
<!DOCTYPE HTML>
enter the following bold code:<?php function sanitizeInput() { } ?>
You’ve just created a function called sanitizeInput. Now let’s make it do something.
-
We want the function to accept a parameter (in this case our form input), do something to it, and then return the variable back to us. Add the following bold code:
function sanitizeInput($myInput) { //do something return $myInput; }
The function now accepts one parameter (it goes in the parentheses), and returns the variable $myInput. The comment that says “do something” is where we will process the variable.
-
OK, now we can actually sanitize the input. First we want to trim away any whitespace the user may enter. Delete the comment and in its place add the following bold code:
function sanitizeInput($myInput) { $myInput = trim($myInput); return $myInput; }
-
Now that the function is at least partly built, we can put it to use. To use it we’ll wrap it around the name and email
$_POST
variables on our page. Add the bold code as shown below:<p><strong>Name:</strong> <?php echo sanitizeInput($_POST['name']); ?></p> <p><strong>Email:</strong> <?php echo sanitizeInput($_POST['email']); ?></p>
Don’t forget the closing parentheses!
-
Save the page and then in a browser go to:
- Mac: localhost:8888/phpclass/form-basic/form.php
- Windows: localhost/phpclass/form-basic/form.php
Add a bunch of spaces before your name and submit the form. You’ll see that the space is automatically removed.
Switch back to your code editor.
-
Next we can add the
htmlentities()
function which will convert any HTML characters to harmless HTML entity equivalents. In the sanitizeInput() function add the following bold code:function sanitizeInput($myInput) { $myInput = trim($myInput); $myInput = htmlentities($myInput, ENT_QUOTES, 'UTF-8'); return $myInput; }
The htmlentities() function takes three parameters:
- The string variable that we want to process.
- How it’ll handle quotes. ENT_QUOTES encodes both double and single quotes. There are other options if you want to leave single quotes alone, but converting all of them is the safest option.
- The character encoding type. Most modern webpages use UTF-8 encoding which allows special characters such as a • or ñ character.
-
Save the page and then in a browser go to:
- Mac: localhost:8888/phpclass/form-basic/form.php
- Windows: localhost/phpclass/form-basic/form.php
-
In the Name field enter the following:
<i>Your Name</i>
Submit the form. You’ll see that the text is not italicized.
View the source of the page and you’ll see that the HTML characters have been converted into their HTML entity equivalent.
Switch back to your code editor.
Switch back to form-action.php.
-
Finish adding sanitizeInput() to the rest of the
$_POST
variables as shown in bold. For the comments field, be sure to addsanitizeInput()
inside thenl2br()
so that the line breaks are preserved.<p><strong>Level:</strong> <?php if ( isset($_POST['level']) ) { echo sanitizeInput($_POST['level']); } ?> </p> <p><strong>Publications:</strong> <?php if ( isset($_POST['publications']) ) { echo sanitizeInput( implode(', ', $_POST['publications']) ); } ?> </p> <p><strong>How often track:</strong> <?php echo sanitizeInput($_POST['howoftentrack']); ?></p> <p><strong>Comments:</strong></p> <p><?php echo nl2br( sanitizeInput($_POST['comments']) ); ?></p>
-
Save the page and then in a browser go to:
- Mac: localhost:8888/phpclass/form-basic/form.php
- Windows: localhost/phpclass/form-basic/form.php
Test everything out and all the form inputs should now be securely output on the action page.
Switch back to your code editor.
Close any open files. We’re done for now.