PHP & MySQL Tutorial
PHP & MySQL Tutorial
Overview
by Graeme Merrall
Original Site: http://hotwired.lycos.com/webmonkey/programming/php/tutorials/tutorial4.html
Graeme Merrall works in New Zealand for KC Multimedia, an Internet/intranet design company. While
sometimes being forced to use ASP, he enjoys spending his time coding in PHP, keeping the grass trimmed, and
scaring his work mates with song lyrics repeated out of context.
Open source has brought a lot more than Linux to the computing world. It has also
given us PHP and MySQL. According to Graeme, PHP and MySQL are the world's
best combination for creating data-driven sites. In the first installment of this three-
lesson tutorial, our Kiwi guide covers everything you need to know to begin
developing database hubs. He gives instructions for installation on both Unix and
Windows, and then goes on to show some simple scripts that will insert information
into a database and display that data on a Web page.
Lesson 2 covers more PHP/MySQL goodies than you could probably imagine.
Graeme starts by showing while loops, then talks about the ever-useful if-else
statement. But this information alone means little if you don't continue and see how
PHP can be used with HTML forms. By the time you've polished off this lesson,
you'll be able to add, edit, and remove information from your database.
In Lesson 3, Graeme shows some of the secrets that will turn your simple data-
driven site into a useful application. As he covers validation, he'll show how to
prevent users from leaving key form fields blank and how to make sure numeric
files don't contain letters. He'll also teach you how PHP handles includes and
functions. Plus you'll see how these two features, when deployed together, can
make the coder's life much easier. Graeme winds it all up with some tearful parting
words and a bit of advice for the aspiring PHP/MySQL coder.
Unless you've been living on Mars for the last six to eight months, you've
heard of open source software (OSS). This movement has got so much
momentum that even the big boys are taking notice. Companies like
Oracle, Informix, and a host of others are releasing their flagship database
products for that poster child of the OSS movement, Linux.
MySQL is a small, compact database server ideal for small - and not so
small - applications. In addition to supporting standard SQL (ANSI), it
compiles on a number of platforms and has multithreading abilities on Unix
servers, which make for great performance. For non-Unix people, MySQL
can be run as a service on Windows NT and as a normal process in
Windows 95/98 machines.
Finally, since both efforts are collaborative in nature, there's always plenty
of support from documentation and mailing lists. Bugs are fixed rapidly,
and requests for features are always heard, evaluated, and if feasible,
implemented.
Enough talk! Let's go over what we're going to cover in this tutorial.
Installing MySQL
Let's jump straight in, grab ourselves a copy of these great packages, and
get hacking! This isn't simple stuff. There are lots of options available to
you for obtaining, compiling, and installing the software. Let's deal with
MySQL first, as we'll need it before we get PHP going.
The precompiled Unix versions and the Windows version are as simple as
unpacking and going, and they don't require much explanation. So let's
compile from the source code. Windows users, please keep in mind that
you need to run mysqld in the mysql/bin directory.
Download the compressed file into your source directory and uncompress
and untar it using gzip and tar. The fast way of doing this is to type:
The xxxx is where you put the version number. This will create a directory
called mysql-xxxx, which contains all the source files. Move to that
directory by typing cd mysql-xxxx and check out the various README and
INSTALL files. They're lifesavers in sticky situations.
You can also specify lots of other options, such as what to compile and
what to skip. Let's assume that we want everything under
/usr/local/mysql on our server. This means we'd type ./configure --
prefix=/usr/local/mysql.
The configure script will run and inspect your system and then build the
necessary files to successfully compile. If it fails, you'll usually get a helpful
error message saying why. Quite often, you'll find the script will fail when
it's looking for threading libraries. Check that you've got MIT-pthreads
If everything goes according to plan, simply type make and go get a coffee.
MySQL is a complex program and takes some time to compile. If you get
an error, check the documentation to see if there is anything specific that
you've missed for your particular OS.
Next, type make install and all the necessary files will be installed in all
the necessary spots. Now you're almost ready to roll! If you are a MySQL
virgin and you've never installed MySQL before, you need to create the
default permissions, so type ... scripts/mysql_install_db to set these
up.
That's it. We're ready to roll. All we need to do is add the ability to start
and stop the server at boot-up and shutdown times. And yes, there's a
script for that as well. Typing mysql.server start starts the server, and
mysql.server stop stops the server. It's kind of obvious, really. To start
the server manually (so you can play without rebooting) enter the root
directory in your MySQL installation (/usr/local/mysql) and type
bin/safe_mysqld &.
Installing PHP
Phew! Hopefully you've got MySQL all up and running by now. That was
almost fun! Now for PHP ... This process is slightly easier, but the array of
options is dazzling. Don't be daunted, though. You can always go back
later and recompile PHP to add or remove options as needed.
But first let's cover Windows. When using PHP, a common practice is to
develop on a Windows machine and then run your site on a Unix server. It
may end up that you will do this yourself, which means you need to be
proficient in installing on both platforms.
Let's grab the Windows binary and uncompress it using our favorite Zip
decompression tool into a directory on your C drive called php3. The
supplied README file deals with the installation in some detail, but here's
the Reader's Digest version: If you want to install PHP to a folder other
than C:\php3, you'll need to edit the .inf file that comes with PHP.
extension=php3_mysql.dll
If you're using Apache for Win32, set up Apache to recognize and parse
PHP files. Depending on the version of Apache you're using, you'll need to
add the following to either the httpd.conf or srm.conf file:
ScriptAlias /php3/"c:/path-to-php-dir/"
AddType application/x-httpd-php3 .php3
Action application/x-httpd-php3"/php3/php.exe"
OK, now that Windows is out of the way, let's get to Unix. Of course, we'll
be compiling from source code. As with MySQL, download and unpack the
source code. Again, PHP comes with a configure script. You can't get away
with going for defaults here, though. Run ./configure -help | more to
see pages and pages of new and interesting options. You have to decide
between compiling as a CGI or as an Apache module. If you are using the
Apache Web server and you are able to recompile it, use the module: It's
faster and easier to use. Otherwise, you can go with the CGI version. We
also need to compile in MySQL support.
For now we'll assume that we're running the module with MySQL support.
If you want to add other options or other libraries, you can do this later.
Type:
./configure --with-apache=/path/to/apache/dir --
with-mysql=/usr/local/mysql
It's time for another coffee. If you start feeling a bit nervous and shaky at
this point, don't worry about it. We all get a little anxious during our first
PHP install. Have some more coffee.
If you've created a CGI version, you're now ready to roll. Simply copy the
resulting executable file into your CGI file. For Apache module users, type
make install to copy files to your Apache directory. From there, follow
the instructions to add a module to Apache and recompile.
You'll need to tell your Web server how to process pages through the PHP
program now. If you're not using Apache, you'll need to check your Web
server documentation on how to get it to process documents with a .php3
extension. Apache 1.3.x users can simply add AddType application/x-
httpd-php3 .php3 to the httpd.conf or srm.conf file. If you're using the
CGI version, you'll need to add the following before AddType:
That's it. With any luck, you've now got MySQL running and PHP
functioning. Don't forget to check the FAQs and documentation if you get
stuck. Also try the mailing lists.
Now that we've managed all that, lets put this stuff in motion!
You'll be glad to know that the really tricky stuff is behind you. Installation
of software is always a black hole because so much changes from system
to system. But with any luck your database is up and running, and PHP is
compiled and installed with our Web server and able to recognize
documents with .php3 extensions.
Let's dive right in and write our first script. Create a text file containing the
following:
<html>
<body>
<?php
echo $myvar;
?>
</body>
</html>
That's it! That's your first PHP script. If you view the HTML source for the
page, you'll see that there is only the text. Hello World
That's because the PHP engine has examined the page, processed any
code blocks that it found, and returned only HTML.
The first thing you'll notice about the script above are the delimiters. These
are the lines that start <?php. This indicates the start of a block of PHP
code, and ?> indicates the end of the block. The power of PHP is that these
can be placed anywhere - and I mean anywhere - in your code in any
number of ways. Later we'll see some interesting uses for these, but for
now let's keep it simple. If you wish, you can also configure PHP to use
short tags, <?, and ?>, but these are not XML compliant, so be careful. If
you're making the switch from ASP, you can even configure PHP to use the
<% and %> delimiters.
Finally, you see that the word myvar begins with a dollar sign. This symbol
tells PHP that this is a variable. We assigned the words "Hello World" to the
variable $myvar. A variable can also contain numbers or an array. Either
way, all variables start with the dollar sign symbol.
The real power of PHP comes from its functions. These are basically
processing instructions. If you add up all of the optional add-ins to PHP,
there are more than 700 functions available. So there's quite a bit you can
do.
Load Up a Database
<html>
<body>
<?php
phpinfo();
?>
</body>
</html>
OK, now we've got our data in the database. Let's do something with it.
Copy and paste the following into a text file and save it in your Web server
document tree with a .php3 extension.
<html>
<body>
<?php
$db = mysql_connect("localhost", "root");
mysql_select_db("mydb",$db);
$result = mysql_query("SELECT * FROM employees",$db);
printf("First Name: %s<br>\n",
mysql_result($result,0,"first"));
printf("Last Name: %s<br>\n", mysql_result($result,0,"last"));
printf("Address: %s<br>\n", mysql_result($result,0,"address"));
printf("Position: %s<br>\n",
mysql_result($result,0,"position"));
?>
</body>
</html>
mysql_select_db() then tells PHP that any queries we make are against
the mydb database. We could create multiple connections to databases on
different servers. But for now, let's leave it to this.
Next, mysql_query() does all the hard work. Using the database
connection identifier, it sends a line of SQL to the MySQL server to be
processed. The results that are returned are stored in the variable
$result.
In this lesson, we're going to dive right in and create some simple yet
useful pages using PHP and MySQL. Let's start by displaying the database
we created yesterday, but with a little more panache.
<html>
<body>
<?php
$db = mysql_connect("localhost", "root");
mysql_select_db("mydb",$db);
$result = mysql_query("SELECT * FROM employees",$db);
echo "<table border=1>\n";
echo "<tr><td>Name</td><td>Position</tr>\n";
while ($myrow = mysql_fetch_row($result)) {
printf("<tr><td>%s %s</td><td>%s</td></tr>\n",
$myrow[1], $myrow[2], $myrow[3]);
}
echo "</table>\n";
?>
</body>
</html>
Now let's examine the loop in more detail. The first few lines you'll
recognize from the example in Lesson 1. Then in the while() loop we
fetch a row from the result and assign it to the array $myrow. Then we
print the contents of the array on the screen with the printf function.
After that it loops around again, and another row is assigned to $myrow. It
will do this until it runs out of rows to grab.
The great thing about a while() loop is that if your query returns no
records, you won't get an error message. The first time through there
won't be any data to assign to $myrow, and the program will just move on.
But if the query returns no data, we have no way of letting the user know,
and we should probably provide some sort of message. This is possible, so
let's do it.
Stay Informed
<html>
<body>
<?php
$db = mysql_connect("localhost", "root");
mysql_select_db("mydb",$db);
$result = mysql_query("SELECT * FROM employees",$db);
if ($myrow = mysql_fetch_array($result)) {
echo "<table border=1>\n";
echo "<tr><td>Name</td><td>Position</td></tr>\n";
do {
printf("<tr><td>%s %s</td><td>%s</tr>\n", $myrow["first"],
$myrow["last"], $myrow["address"]);
} while ($myrow = mysql_fetch_array($result));
echo "</table>\n";
} else {
echo "Sorry, no records were found!";
}
?>
</body>
</html>
There are a number of new features introduced
here, but they're quite simple. First, there's the
mysql_fetch_array() function. This is exactly the
same as mysql_fetch_row() with one nice
exception: Using this function, we can refer to
fields by their names (such as $myrow["first"])
rather than their numbers. This should save us
some headaches. We've also introduced a do/while
Link Intelligently
First off, lets query our database again and list the
employee names. Look at the following script.
Much of this should look pretty familiar by now.
<html>
<body>
<form method="post" action="<?php echo $PHP_SELF?>">
First name:<input type="Text" name="first"><br>
Last name:<input type="Text" name="last"><br>
Address:<input type="Text" name="address"><br>
Position:<input type="Text" name="position"><br>
OK, let's add some code that will check for the
form input. Just to prove that the form input does
make it through, I'll dump all the variables to the
screen with $HTTP_POST_VARS. This is a useful
debugging feature. If you ever need to see all the
variables on a page, use $GLOBALS.
<html>
<body>
<?php
if ($submit) {
// process form
while (list($name, $value) = each($HTTP_POST_VARS)) {
echo "$name = $value<br>\n";
}
} else{
// display form
?>
<form method="post" action="<?php echo $PHP_SELF?>">
First name:<input type="Text" name="first"><br>
Last name:<input type="Text" name="last"><br>
Address:<input type="Text" name="address"><br>
Position:<input type="Text" name="position"><br>
<input type="Submit" name="submit" value="Enter information">
</form>
<?php
} // end if
?>
</body>
<html>
<body>
<?php
if ($submit) {
// process form
$db = mysql_connect("localhost", "root");
mysql_select_db("mydb",$db);
$sql = "INSERT INTO employees (first,last,address,position)
VALUES ('$first','$last','$address','$position')";
$result = mysql_query($sql);
echo "Thank you! Information entered.\n";
} else{
// display form
?>
<form method="post" action="<?php echo $PHP_SELF?>">
First name:<input type="Text" name="first"><br>
Last name:<input type="Text" name="last"><br>
Address:<input type="Text" name="address"><br>
Position:<input type="Text" name="position"><br>
<input type="Submit" name="submit" value="Enter information">
</form>
<?php
} // end if
?>
</body>
</html>
<html>
<body>
<?php
$db = mysql_connect("localhost", "root");
mysql_select_db("mydb",$db);
if ($id) {
// query the DB
$sql = "SELECT * FROM employees WHERE id=$id";
$result = mysql_query($sql);
$myrow = mysql_fetch_array($result);
?>
<form method="post" action="<?php echo $PHP_SELF?>">
<input type=hidden name="id" value="<?php echo $myrow["id"]
?>">
First name:<input type="Text" name="first" value="<?php echo
$myrow["first"] ?>"><br>
Last name:<input type="Text" name="last" value="<?php echo
$myrow["last"] ?>"><br>
Address:<input type="Text" name="address" value="<?php echo
$myrow["address"] ?>"><br>
Position:<input type="Text" name="position" value="<?php echo
$myrow["position"] ?>"><br>
<input type="Submit" name="submit" value="Enter information">
</form>
<?php
} else {
// display list of employees
$result = mysql_query("SELECT * FROM employees",$db);
while ($myrow = mysql_fetch_array($result)) {
printf("<a href=\"%s?id=%s\">%s %s</a><br>\n", $PHP_SELF,
$myrow["id"], $myrow["first"], $myrow["last"]);
}
}
?>
</body>
</html>
<html>
<body>
<?php
$db = mysql_connect("localhost", "root");
mysql_select_db("mydb",$db);
if ($id) {
if ($submit) {
$sql = "UPDATE employees SET
first='$first',last='$last',address='$address',position='$posit
ion' WHERE id=$id";
$result = mysql_query($sql);
echo "Thank you! Information updated.\n";
} else {
// query the DB
$sql = "SELECT * FROM employees WHERE id=$id";
$result = mysql_query($sql);
$myrow = mysql_fetch_array($result);
?>
<form method="post" action="<?php echo $PHP_SELF?>">
<input type=hidden name="id" value="<?php echo $myrow["id"]
?>">
First name:<input type="Text" name="first" value="<?php
echo $myrow["first"] ?>"><br>
Last name:<input type="Text" name="last" value="<?php echo
$myrow["last"] ?>"><br>
Address:<input type="Text" name="address" value="<?php echo
$myrow["address"] ?>"><br>
Position:<input type="Text" name="position" value="<?php
echo $myrow["position"] ?>"><br>
<input type="Submit" name="submit" value="Enter
information">
</form>
<?php
}
} else {
// display list of employees
$result = mysql_query("SELECT * FROM employees",$db);
while ($myrow = mysql_fetch_array($result)) {
printf("<a href=\"%s?id=%s\">%s %s</a><br>\n", $PHP_SELF,
$myrow["id"], $myrow["first"], $myrow["last"]);
PHP/MySQL Tutorial Page 18 of 32
}
}
?>
</body>
</html>
<html>
<body>
<?php
$db = mysql_connect("localhost", "root");
mysql_select_db("mydb",$db);
if ($submit) {
// here if no ID then adding else we're editing
if ($id) {
$sql = "UPDATE employees SET
first='$first',last='$last',address='$address',position='$posit
ion' WHERE id=$id";
} else {
$sql = "INSERT INTO employees (first,last,address,position)
VALUES ('$first','$last','$address','$position')";
}
// run SQL against the DB
$result = mysql_query($sql);
echo "Record updated/edited!<p>";
} elseif ($delete) {
// delete a record
$sql = "DELETE FROM employees WHERE id=$id";
$result = mysql_query($sql);
echo "$sql Record deleted!<p>";
} else {
// this part happens if we don't press submit
<html>
<body>
<?php
include("emptyfile.inc");
?>
</body>
</html>
<?php
mysql_select_db("mydb",$db);
?>
<head>
<title>
</title>
</head>
<body>
<?php
include("header.inc");
echo "<tr><td>Name</td><td>Position</tr>\n";
echo "</table>\n";
include("footer.inc");
?>
Simple Validation
Imagine for a moment that we've got our database nicely laid out and
we're now requesting information from users that will be inserted into the
database. Further, let's imagine that you have a field in your database
waiting for some numeric input, such as a price. Finally, imagine your
application falling over in a screaming heap because some smart aleck put
text in that field. MySQL doesn't want to see text in that portion of your
SQL statement - and it complains bitterly.
Validation simply means that we'll examine a piece of data, usually from an
HTML form, and check to make sure that it fits a certain model. This can
range from ensuring that a element is not blank to validating that an
element meets certain criteria (for example, that a numeric value is
stipulated or that an email address contains an @ for an email address).
Validation can be done on the server side or on the client side. PHP is used
for server-side validation, while JavaScript or another client-based scripting
language can provide client-side validation. This article is about PHP, so
we're going to concentrate on the server end of things. But if you're
looking for some ready-made, client-side validation scripts, check out the
Webmonkey code library.
Let's ignore our database for the moment and concentrate on PHP
validation. If you wish, you can add additional fields to our employee
database quite simply by using the MySQL ALTER statement - that is, if
you want to commit to the values that we'll validate.
There are several useful PHP functions we can use to validate our data,
and they range from simple to highly complex. A simple function we could
use might be strlen(), which tells us the length of the variable.
Let's start with a simple example. We'll check to see whether a variable
does or does not exist.
<html>
<?php
if ($submit) {
if (!$first || !$last) {
} else {
// process form
if (!$submit || $error) {
echo $error;
?>
<P>
<br>
<br>
</form>
<?php
} // end if
?>
</body>
</html>
The keys to this script are the nested conditional statements. The first
checks to see whether the Submit button has been pressed. If it has, it
goes on to check that both the variables $first and $last exist. The ||
symbol means "or" and the ! symbol means "not." We could also rewrite
The function for this is, as you already know, strlen(). It simply returns a
number equal to the number of characters in the variable being tested.
Here, I modified the script above to check the length of $first and $last.
<html>
<body>
<?php
if ($submit) {
} else {
// process form
if (!$submit || $error) {
echo $error;
?>
<P>
<br>
<br>
</form>
<?php
?>
</body>
</html>
Run this script and try entering six or fewer letters to see what happens.
It's simple yet quite effective.
Not-So-Simple Validation
Let's talk a bit about using regular expressions with the ereg() and
eregi() functions. As I said earlier, these can be either quite complex or
very simple, depending on what you need.
Rather than delve into the mysteries of regular expressions, I'll provide
some examples. You can use the same form we created on the previous
page - just paste in the lines below to see how they work.
First, let's make sure that text only has been entered into a form element.
This regular expression tests true if the user has entered one or more
lowercase characters, from a to z. No numbers are allowed:
Now, let's extend this expression to check whether the string is four to six
characters in length. Using [[:alpha:]] is an easy way to check for valid
alphabetic characters. The numbers in the braces check for the number of
occurrences. And note that the ^ and $ indicate the beginning and end of
the string.
if (!ereg("^[[:alpha:]]{4,6}$", $first) ||
!ereg("^[[:alpha:]]{4,6}$", $last)) {
Finally, let's build a regular expression that will check an email address'
validity. There's been plenty of discussion about the effectiveness of
checking for email addresses in this way. Nothing's completely foolproof,
but what I have below works pretty well.
I took this gem from the PHP mailing list. It's a great resource - use it. And
yes, this is as scary as it looks.
if (!ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'.
'[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'.
'[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $last)) {
Don't spend too much time looking at this. Just move on to the next page.
Functions
Enjoy that last regex expression? Fun, wasn't it? Wouldn't it be even more
fun to enter that chunk on a dozen different pages that need to process
email addresses?! Think about the joy of finding a typo in that mess - and
doing it a dozen times no less. But of course, there's a better way.
Remember when we talked about include files earlier in this lesson? They'll
allow us to create a piece of code like the email checker and include it
multiple times across several pages. This way, when we want to change
the code, we need edit only one file, not many.
We've already used functions plenty of times. Every time we query the
database or check the length of a string we're using functions. These
functions are built into PHP. If you're a keen coder, you can extend PHP
with your own customized functions. But that's a bit advanced for this
tutorial. Instead we'll create functions that will reside within our PHP script.
A function is simply a block of code that we pass one or more values to.
The function then processes the information and returns a value. The
function can be as simple or complex as we like, but as long as we can
pass a value in and get one out, we don't really care how complex it is.
That's the beauty of functions.
So let's create a function. We'll start simply. We need to give the function a
name and tell it what variables to expect. We also need to define the
function before we call it.
<html>
<?php
return $newnum;
echo addnum(4,5);
?>
</body>
</html>
That's it! First, we created our function. Notice how we defined two new
variables, called $first and $second. When we call the function, each
variable is assigned a value based on the order in which it appears in the
list - 4 goes to $first, 5 to $second. Then we simply added the two
numbers together and returned the result. "Return" here simply means to
send the result back. At the end of the script we print the number 9.
Let's create something that's more useful to our database application. How
about something that gracefully handles errors? Try this:
<html>
<body>
<?php
function do_error($error) {
echo "Best you get hold of the site admin and let her know.";
die;
do_error($db_error);
?>
</html>
Before running this, try shutting down MySQL or using a bogus username
or password. You'll get a nice, useful error message. Observant readers
will notice the @ symbol in front of mysql_connect(). This suppresses
error messages so that you get the information only from the function.
You'll also see we were able to pass a variable into the function, which was
defined elsewhere.
Remember that I said functions use their own private variables? That was
a little white lie. In fact, you can make variables outside of a function
accessible to the function. You might create a function to query a database
and display a set of results over several pages. You don't want to have to
pass the database connection identifier into the function every time. So in
this situation, you can make connection code available as a global variable.
For example:
<html>
<body>
<?php
function db_query($sql) {
global $db;
$result = mysql_query($sql,$db);
return $result;
$result = db_query($sql);
?>
</body>
</html>
This is a basic function, but the point is that you don't need to send $db
through when you call the function - you can make it available using the
word global. You can define other variables as global in this statement, just
separate the variable names by a comma.
Finally, you can look like a real pro by using optional function variables.
Here, the key is to define the variable to some default in the function, then
when you call the function without specifying a value for the variable, the
default will be adopted. But if you do specify a value, it will take
precedence.
<html>
<body>
<?php
return $db;
$old_db = db_connect();
$new_host = "site.com";
$new_db = db_connect($new_host);
?>
</body>
</html>
Isn't that cool? The variables used inside the function were defined when
the function was defined. The first time the function is called, the defaults
are used. The second time, we connect to a new host, but with the same
username and password. Great stuff!
Think about where you could use other functions in your code. You could
use them for data checking, performing routine tasks, and so on. I use
them a lot when processing text for display on a Web page. I can check,
parse, and modify the text to add new lines and escape HTML characters in
one fell swoop.
Closing Advice
Finally, there's PHP. The PHP Web site has nearly everything you need,
from a comprehensive manual to mailing-list archives to code repositories.