PHP and forms
In this section, you'll look at arrays and at ways to work with form data. You'll also look at how to control the flow of a PHP script, such as loops and if-then statements.
Creating and using forms in PHP
Developers created PHP as a web programming language. In fact, while you can run PHP from the command line, it's rare for anyone to use the language outside of the web application arena. The upshot is that one of your most common tasks as a PHP programmer will be to use web forms.
You create web forms using HTML, and when a user submits the form, the browser sends an array of information to the server.
Start by creating the registration page for your application. Ultimately, users will enter their information, and you'll validate it, or check it for completeness, before saving it in a database. For now, just create the basic form. Create a new file called registration.php and add the following in Listing 6.
Listing 6. Creating a registration page
<html>
<head><title>Workflow System</title></head>
<body>
<h1>Register for an Account:</h1>
<form action="registration_action.php" method="GET">
Username: <input type="text" name="name" /><br />
Email: <input type="text" name="email" /><br />
Password: <input type="password" name="pword" /><br />
<input type="submit" value="GO" />
</form>
</body>
</html> |
Here you have a simple form (contained within the
form
element) with two text inputs: a password input, and
a submit button. Save the file in the document root (with registration_action.php).
To open it, point your browser at http://localhost/registration.php
and type in each of the fields. You should see something like Figure 3.
Figure 3. Register for an Account form
Notice that the password box does not display the actual content you're typing; this type of form element is meant to obscure sensitive information from someone who might be looking over your shoulder. But what happens when you click the GO button?
When you created the form, you created the actual
form
element as: <form action="registration_action.php" method="GET">.
The element has two pieces of information. The first, action, tells the
browser where to send the information. In this case, it's going to the page you created earlier, registration_action.php.
The second, method, tells the browser how to send the data.
Let's see how it works. Fill in some data (if you haven't already) and click the GO button. You should see a result similar to Figure 4.
Figure 4. Outputting the data
In this case, notice that the information seems to be
incorrect—it's not what you actually submitted—but
that's because you haven't yet adjusted that page to look at the data being submitted.
But take a look at the URL: http://localhost/registration_action.php?name=nickChase&email=nickchase%40noTooMi.com&pwor
d=asupersecretpassword.
Notice that for each form element that has a name, you have a name-value pair in the URL, separated
by ampersands.
The URL looks like this because you used the
GET
method, which tells the browser to send the data this way.
You'll also look at Using POST, which
involves sending the data differently, but first
take a look at actually retrieving this data from within a PHP page.
Now that you've submitted the form, you've got to get the data into the actual response page, registration_action.php. Make the changes shown in Listing 7 to that file.
Listing 7. Getting the data to the response page
...
<body>
<p>You entered:</p>
<?php
$username = $_GET['name'];
$password = $_GET['pword'];s
echo "<p>Username = " . $username . "</p>";
echo "<p>Password = " . $password . "</p>";
?>
</body>
</html> |
What you're doing is pulling the named value out of the
$_GET
array. There will be more about arrays in
a moment, but for now notice that if you refresh the browser, your actual answers appear,
as shown in Figure 5.
Figure 5. Correct information in the browser
You can pull any piece of submitted information by its name, but because this is an array, you also have other options.
PHP enables you to create arrays, or lists of values, which allow you to easily reference a group of values all at one time. For example, you can create an array of values and output them to the page (see Listing 8).
Listing 8. Creating an array of values
$formnames = array("name", "email", "pword");
echo "0=".$formnames[0]."<br />";
echo "1=".$formnames[1]."<br />";
echo "2=".$formnames[2]."<br />"; |
The array() function returns a value that is an array of the values passed to it.
(Functions will be dealt with later, but for now, understand that you call it
and it returns a value you assign to a variable.)
Notice that the first value has an index of 0, rather than 1. Notice also that you specified which value you wanted by adding the index in brackets after the name of the array variable. This script produces the output shown in Listing 9.
Listing 9. Array output
0=name<br /> 1=email<br /> 2=pword<br /> |
This action
is similar
to the way in which you access the form values, and that's no accident. The
$_GET
variable is a
special kind of an array called an
associative
array, which means that instead of a numeric index, each
value has a key.
When you submit the form, you're essentially creating an array as shown in Listing 10.
Listing 10. Submitting the form creates an array
$_GET = array("name" => "roadnick",
"email" => "ibmquestions@nicholaschase.com",
pword" => "supersecretpassword");
|
That's what enables you to extract individual values, such as$_GET["name"].
You don't have to do this individually, however.
Getting array information by the numbers
Associative arrays can be extremely handy in dealing with data, but situations frequently arise in which you don't actually know what the structure of the array looks like. For example, you might be building a generic database routine that receives an associative array from a query.
Fortunately, PHP provides two functions that make your life a little easier (see Listing 11).
Listing 11. The
array_keys() and the array_values() functions
...
<body>
<p>You entered:</p>
<?php
$form_names = array_keys($_GET);
$form_values = array_values($_GET);
echo "<p>" . $form_names[0] . " = " . $form_values[0] . "</p>";
echo "<p>" . $form_names[1] . " = " . $form_values[1] . "</p>";
echo "<p>" . $form_names[2] . " = " . $form_values[2] . "</p>";
?>
</body>
... |
The
array_keys()
and
array_values()
functions each return regular numeric arrays of
information, so you can use those arrays to pull the data out using the numeric indexes, as shown in
Figure 6.
Figure 6. Arrays to pull out data using numeric indexes
Still, there's got to be a more convenient way. For example, what if you don't actually know how many values there are? PHP provides several ways of dealing with associative arrays, the most convenient being determined by what information you already have. Let's look at two other ways of accomplishing this same task next.
One very common task in PHP is looping through a number of values. You can accomplish that easily using a for-next loop. A for-next loop runs through a number of values based on its definition. Let's look at an example of this the loop in Listing 12.
Listing 12. for-next loop
for ($i = 0; $i < 10; $i++) {
echo $i . " ";
} |
PHP initially assigns a value of
0
to
$i
because that is what's specified at the beginning
of the loop. The loop continues as long as
$i
is less than 10, and each time the loop executes, PHP increments
the value of
$i
by one.
This the output:
0 1 2 3 4 5 6 7 8 9 |
What this means is that if you can find out how many values are in the
$_GET
array—which you can do—you can easily loop through all of the values
provided by the form
as shown in Listing 13.
Listing 13. Looping through all the values provided by the form
...
<body>
<p>You entered:</p>
<?php
$form_names = array_keys($_GET);
$form_values = array_values($_GET);
for ($i = 0; $i < sizeof($_GET); $i++) {
echo "<p>".$form_names[$i]." = " . $form_values[$i] . "</p>";
}
?>
</body>
... |
The
sizeof()
function gives you the number of values in the
$_GET
array. You can use
that data to tell you when to stop the loop, as shown in Figure 7.
Figure 7. Using the sizeof function to stop the loop
With
$_GET
as an associative array, you actually have yet another option: the
foreach
loop.
Associative arrays are so common in PHP that the language also provides an easy way to get at the
data
without having to go through the process of extracting the keys and values. Instead, you can use a
foreach
loop, which directly manipulates the array.
Consider, for example, the code in Listing 14.
Listing 14. Using a
foreach loop
...
$form_values = array_values($_GET);
foreach ($_GET as $value) {
echo "<p>" . $value . "</p>";
}
?>
... |
The first time PHP executes the loop, it takes the first value in the
$_GET
array and assigns that
value to$value, which it then outputs. It then returns to the top of the
loop and assigns the next
value to $value, doing this for each value in
$_GET (hence, the name).
The end result is the output shown in Listing 15.
Listing 15. Output from the
foreach loop<p>roadnick</p> <p>ibmquestions@nicholaschase.com</p> <p>supersecretpassword</p> |
Even more handy, however, is the ability to extract the value and the key as shown in Listing 16.
Listing 16. Extracting the value and the key
...
$form_values = array_values($_GET);
foreach ($_GET as $key=>$value) {
echo "<p>" . $key . " = " . $value . "</p>";
}
?>
... |
This brings you back to the original result (see Figure 8).
Figure 8. The original result
While on the subject of form values, you need to deal with a situation that comes up occasionally: when you have multiple form values with a single name. For example, since the users can't see what they are typing for the password, you may want to make them type it twice to confirm that they haven't made a mistake by adding the code in Listing 17 to registration.php:
Listing 17. Multiple form values with a single name
... Username: <input type="text" name="name" /><br /> Email: <input type="text" name="email" /><br /> Password: <input type="password" name="pword[]" /><br /> Password (again): <input type="password" name="pword[]" /><br /> <input type="submit" value="GO" /> ... |
Notice that the name of the
pword
field has changed slightly. Because you're going to retrieve
multiple values, you need to treat the password itself as an array. Yes, that means you have an
array value that is another array.
So, if you submit the form now, it creates a URL: http://localhost/registration_action.php?name=nickChase&email=nickchase%40noTooMi.com
&pword%5B%5D=asupersecretpassword&pword%5B%5D=asupersecretpassword.
(The value %5B%5D is the url-encoded version of [].)
Submitting the form is the same as creating arrays (see Listing 18).
Listing 18. Submitting the form creates an array
$passwords = array("asupersecretpassword", "asupersecretpassword");
$_GET = array("name"=>"nickChase",
"email"=>"nickChase@noTooMi.com",
"pword"=>$passwords); |
All this means that if you want to see the password values, you'll need to access them as a numeric array, as shown in Listing 19.
Listing 19. Accessing the password values as a numeric array
...
foreach ($_GET as $key=>$value) {
echo "<p>".$key." = " . $value . "</p>";
}
$passwords = $_GET["pword"];
echo "First password = ".$passwords[0];
echo "<br />";
echo "Second password = ".$passwords[1];
... |
If you submit the form (or refresh the page), you can see the difference, as shown in Figure 9.
Figure 9. Submitting the form
Notice that the password field is now output as Array, but you can access
its values directly.
So far, you've been using the
GET
method for submitting data, which, as you have seen, places the data
right in the URL. Now, sometimes this is appropriate, and sometimes it's not.
For example, you can use this technique to
simulate submitting a form using a link, but if you have a large amount of data—coming, say,
from a textarea
in which users can enter comments—this technique isn't the best way to accomplish your goal.
For one thing, web servers typically limit the number of characters that they'll accept in a
GET request.
For another thing, good technique and standards requirements say that you never use
GET
for an operation
that has "side effects," or that actually
does
something. For example, right now you're just looking at data, so
no side effects affect the operation. But, ultimately, you're going to add the data to the database,
which is, by definition,
a side effect.
Many web programmers aren't aware of this particular restriction, which can lead to problems. Using
GET,
particularly as a URL, can lead to situations in which systems perform operations multiple times
because a user has
bookmarked the page, or because a search engine has indexed the URL, unaware it's actually
updating a database or
performing some other action.
So, in these instances, you'll have to use
POST
instead.
Using the
POST
method instead of the
GET
method is actually pretty straightforward.
First you need to change the registration.php page as shown in Listing 20.
Listing 20. Using
POST method instead of GET on the registration page... <h1>Register for an Account:</h1> <form action="registration_action.php" method="POST"> Username: <input type="text" name="name" /><br /> ... |
Now when you submit the form, the URL is bare:
http://localhost/registration_action.php |
To retrieve the data, you have two choices. The first is to use the
$_POST array rather than the
$_GET array in
registration_action.php, as shown in Listing 21.
Listing 21. Using the
$_POST array to retrieve the data
...
<body>
<p>You entered:</p>
<?php
foreach ($_POST as $key=>$value) {
echo "<p>".$key." = " . $value . "</p>";
}
$passwords = $_POST["pword"];
echo "First password = ".$passwords[0];
echo "<br />";
echo "Second password = ".$passwords[1];
?>
</body>
...
|
You can work with the
$_POST
array in exactly the same way you worked with the
$_GET
array.
The good thing about this method is that you control precisely what it is your script is looking at.
The bad thing is that if you want to debug by putting something into the URL, you have to change your script.
One common way to get around this problem is to use a third array, $_REQUEST,
which includes data passed in both places (see Listing 22).
Listing 22. Using a
$_REQUEST array for debugging
...
<?php
foreach ($_REQUEST as $key=>$value) {
echo "<p>".$key." = " . $value . "</p>";
}
$passwords = $_REQUEST["pword"];
echo "First password = ".$passwords[0];
... |
Error-checking: The if-then statement
Before moving on, it doesn't make any sense to request that the user type the password twice if you don't make sure that both attempts match. To do that, you'll use an if-then statement as shown in Listing 23.
Listing 23. Using an if-then statement
...
$passwords = $_POST["pword"];
echo "First password = ".$passwords[0];
echo "<br />";
echo "Second password = ".$passwords[1];
if ($passwords[0] == $passwords[1]) {
echo "<p>Passwords match. Thank you.</p>";
} else {
echo "<p>Passwords don't match. Please try again.</p>";
}
...
|
In an if-then statement, if the expression in the parentheses (in this example,
$passwords[0] == $passwords[1]) is true, PHP executes the statements in
the first set of brackets. If it's
false, it doesn't. In this case, you've also included an alternate course of action to take if the
statement is false.
Notice that rather than saying
$passwords[0] = $passwords[1]
with a single equals sign, you said
$passwords[0] == $passwords[1]
with a double equals sign. The double equals sign is the comparative operator.
It actually detects whether the two are equal. The single equals sign is the assignment operator.
With a single equals
sign, when you executed the statement, PHP would simply assign the value of
$passwords[1]
to
$passwords[0], which is clearly not what you wanted.
In this case, the page gives the user a warning if the passwords don't match, as shown in Figure 10.
Figure 10. Warning issued if passwords don't match
Two more handy operators are the
and
operator (&&) and the
or
operator
(||). Listing 24 shows them in action.
Listing 24. The and and the or operators
if (($today == "Monday") && ($status == "Not a holiday")) {
echo "GO TO WORK!!!";
} |
In this case, the expression is true only if today is Monday and it's not a holiday. The or operator returns true if any of the components are true.




