PHP is a language that has outgrown its name.It was originally conceived as a set of macros to help coders maintian personal home pages,and its name grew from its purpose.Since then,PHP's capabilities have been extended,taking it beyond a set of utilities to a full-featured programming language,capable of managing huge database-driven online environments. PHP is now officially known as PHP:Hypertext preprocessor.It is server-side scripting language usually written in an HTML context.Unlike an ordinary HTML page, a PHP script is not send directly to a client by the server;instead,it is parsed by the PHP binary or module.HTML elements in the script can query database,create images,read and write files,talk to remove servers-the possibilities are endless.The output from PHP code is combined with the HTML in the script and the result send to the user.
PHP of Development
To many people,"Open source" simply means free,which is.of course,benefit in itself.
This may sound a little foreign to all you folks coming fron a non UNIX background,but PHP doesnot cost anything.You can give it to your friends,print it out and hang it on your wall or eat it for lunch.Welcome to the world of Open source software!smile,be happy,the world is good.For the full legaless,see the official license.
Well-maintained open source projexts offer users additional benefits,though.You benefit from an accessible and committed community who offer a wealth of experience in the subject.Chances are that any problem you encounter in your coding can be answered swifty and easily with a little research.If that fails,a question sent to a mailing list can yield an intelligent,authoritative response.
You also can be sure that bugs will be addressed as they are found,and that new features will be made available as the need is defined.You will not have to wait for the next commercial release before taking advantage of improvements.
There is not vested interest in a particular server product or operating system.You are free to make choices that suit your needs or those of your clients,secure that your code will run whatever you decide.
Performance
Because of the powerful Zend engine,PHP 4 compares well with ASP in benchmark tests,beating it in some tests.Compiled PHP leaves ASP far behind.
Portability
PHP is designed to run on many operting systems and to cooperate with many servers and database. You can build for a UNIX evvironment and shift your work to NT without a problem.You can test a project with Personal web server and install it on a UNIX system running On PHP as a Apache module.
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
$myvar =
"Hello World";
echo $myvar;
?>
</body>
</html>
Now
call up the URL, for instance, http://myserver/test.php3. You should see a page
containing the text "Hello World." If you get an error message, check
the PHP documentation to see if you set things up properly.
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 things 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.
Another
thing you'll notice is the semicolon on the end of each line. These are known
as separators and serve to distinguish one set of instructions from another. It
is feasible to write an entire PHP script on one line and separate the portions
with semicolons. But that would be a mess, so we'll add a new line after each
semicolon. Just remember that each line must end in a semicolon.
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.
Now
let's add some MySQL to the picture.
<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>
Let's explain what
happens here. The mysql_connect() function opens a link
to a MySQL server on the specified host (in this case it's localhost) along
with a username (root). If you needed to specify a password, you'd add it here
as well. The result of the connection is stored in the variable $db. 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.
Finally, mysql_result() is used to display the values of fields from our query. Using $result, we go to the first row, which is numbered 0, and display the value of the specified fields.
<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>
You probably
noticed that we introduced a couple of new features here. Most obvious is the while() loop. The loop says that as long as there
are new rows of data to be grabbed (using the mysql_fetch_row() function), assign that row to the $myrow variable. Then execute the instructions
between the curly brackets ({}). Take a look for a second, and this should make
sense. The mysql_fetch_row() function bears a closer look. One small problem with mysql_fetch_row() is that it returns an array that supports only numeric references to the individual fields. So the first field is referred to as 0, the second as 1, and so on. With complex queries this can become something of a nightmare.
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.
Take a
look at this script.
<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 loop and an if-else statement.
The
if-else statement says that if we can assign a row to $myrow, then
continue; otherwise skip to the else section and do what's in
there.
The
do/while loop is a variation of the while() loop we used on the
last page. We need the do/while loop here for a very good reason: With the
initial if statement, we assigned the first row returned by the query to the
variable $myrow. If at this point we executed a regular while statement (such as while ($myrow =
mysql_fetch_row($result)), we'd be kicking the first record out of the variable and
replacing it with the second record. But the do/while loop lets us test the
condition after the code has been run once. So there's no chance of us
accidentally skipping a row.
Finally,
if there are no records returned at all, the statements contained in the else{}
portion will be executed. To see this portion in action, change the SQL
statement to SELECT * FROM employees WHERE id=6 or something else that
will return no records.
Now
let's extend this looping and if-else code to make one fancy-schmancy page.
You're going to love it.
Right
now I'm going to work with the querystring. As you should know, there are three
ways to get information into the querystring. The first is to use the GET
method in a form. The second is to type the information into the URL on your
browser. And third, you can embed a querystring in a standard link. Just make
the anchor tag look something like this: <a
href="http://my_machine/mypage.php3?id=1">. We're going to use
this technique right now.
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>
<?php
$db =
mysql_connect("localhost", "root");
mysql_select_db("mydb",$db);
$result =
mysql_query("SELECT * FROM employees",$db);
if ($myrow =
mysql_fetch_array($result)) {
do {
printf("<a
href=\"%s?id=%s\">%s %s</a><br>\n", $PHP_SELF,
$myrow["id"], $myrow["first"], $myrow["last"]);
} while ($myrow =
mysql_fetch_array($result));
} else {
echo "Sorry, no records were
found!";
}
?>
</body>
</html>
Everything's
about the same except the printf
function, so let's look at it in some detail.
First
notice that each quotation mark is preceeded by a backslash. The backslash
tells PHP to display the character following it, rather than treat it as part
of the code. Also note the use of the variable $PHP_SELF. This variable, which
stores the script's name and location, is passed along with every PHP page.
It's helpful here because we just want this file to call itself. Using
$PHP_SELF, we can be sure that will happen, even if the file is moved to
another directory - or even another machine.
As I
just mentioned, these links will recall the page. On the second time through,
however, some information will be added to the querystring.
PHP
does a nifty thing when it sees a name=value pair in the querystring. It
automatically creates a variable with the name and value the querystring
indicated. This feature allows us to test if it's the first or second time
through this page. All we have to do is ask PHP if the variable $id exists.
We've
managed to get data from a database without much difficulty. But what about
sending data the other way? It's not a problem with PHP.
First
let's create a page with a simple form.
<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>
<input
type="Submit" name="submit" value="Enter
information">
</form>
</body>
</html>
Note
the use of $PHP_SELF again. Like I said in Lesson 1, you can use PHP anywhere
inside your HTML code. You'll also notice that each form element matches the
field name in the database. This is not compulsory; it's just a good idea so
you can get your head around your code later on.
Also
notice that I've given the Submit button a name
attribute. I've done this so I can test for the existence of a $submit variable. That way, when the page is called again, I'll know
whether someone used this form.
I should
mention that you don't have to have a page that loops back on itself. You can
span two, three, or more pages, if you like. This way everything stays compact.
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>
Now
that this is looking good, let's take the form information and post it to the
database.
<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>
You've
now inserted data into the database. It's still far from perfect. What if
someone leaves a field blank or enters text when we want a numeric entry? What
if there's an error somewhere?
Throughout
this tutorial, I've been loading the SQL statement into a variable ($sql) before firing the query at the database with mysql_query(). This is useful for debugging. If
something goes wrong, you can always echo the SQL to the screen to examine it
for mistakes.
We
already know how to get data into the database. Now let's try modifying records
that are already in the database. Editing data combines two elements we've
already seen: displaying data on the screen and sending data back to the
database via form input. However, editing is slightly different in that we have
to show the appropriate data in the form.
First,
let's recycle the code from Lesson 1 to display the employee names on our page.
But this time through, we're going to populate our form with employee
information. It should look a little like this:
<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>
We just
echoed the field information into the value
attribute of the each element, which was fairly easy. Let's build on this a
little more. We will add the ability to send the edited code back to the
database. Again, we're going to use the Submit button to test whether we need
to process the form input. Also note the slightly different SQL statement we
use.
<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='$position' 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"]);
}
}
?>
</body>
</html>
And
that's that. We've managed to combine most of the features we've seen into one
script. You can also see how we've used an if()
statement inside another if()
statement to check for multiple conditions.
It's
time to put it all together and make one killer script.
We'll
finish up this lesson by putting everything into a single page that can add,
edit, and remove entries from the database. It's an extension of what we've
covered so far and makes for a good review. Let's take a look.
<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='$position' 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
if (!$id) {
// print the list if there is not editing
$result = mysql_query("SELECT * FROM
employees",$db);
while ($myrow = mysql_fetch_array($result))
{
printf("<a href=\"%s?id=%s\">%s %s</a>
\n", $PHP_SELF, $myrow["id"], $myrow["first"],
$myrow["last"]);
printf("<a
href=\"%s?id=%s&delete=yes\">(DELETE)</a><br>",
$PHP_SELF, $myrow["id"]);
}
}
?>
<P>
<a href="<?php echo
$PHP_SELF?>">ADD A RECORD</a>
<P>
<form method="post"
action="<?php echo $PHP_SELF?>">
<?php
if ($id) {
// editing so select a record
$sql = "SELECT * FROM employees WHERE
id=$id";
$result = mysql_query($sql);
$myrow = mysql_fetch_array($result);
$id = $myrow["id"];
$first = $myrow["first"];
$last = $myrow["last"];
$address = $myrow["address"];
$position = $myrow["position"];
// print the id for editing
?>
<input type=hidden name="id"
value="<?php echo $id ?>">
<?php
}
?>
First name:<input type="Text"
name="first" value="<?php echo $first
?>"><br>
Last name:<input type="Text"
name="last" value="<?php echo $last ?>"><br>
Address:<input type="Text" name="address"
value="<?php echo $address ?>"><br>
Position:<input type="Text"
name="position" value="<?php echo $position
?>"><br>
<input type="Submit"
name="submit" value="Enter information">
</form>
<?php
}
?>
</body>
</html>
This
looks complex, but it really isn't. The script is broken up into three parts.
The first if() statement checks to see
whether the Submit button has been pressed, and if it has, it checks to see
whether the variable $id exists. If doesn't,
then we're adding a record. Otherwise, we're editing a record.
Next we
check to see whether the variable $delete
exists. If it does, we delete a record. Note that with the first if() statement we checked for a variable that came through as a POST,
and in this one, the variable would be part of a GET.
Finally,
we take the default action that displays the list of employees and the form.
Again we check for the existence of the $id
variable. If it exists, we query the database to display the relevant record.
Otherwise, we display a blank form.
We've
now put all we've learned into one script. We used while() loops and if()
statements, and we ran the gamut of the basic SQL statements - SELECT, INSERT,
UPDATE, and DELETE. Lastly, we've looked at how we can pass information from
one page to another using URLs and form input.
We all
know the basics of includes, right? Contents of an external file are referenced
and imported into the main file. It's pretty easy: You call a file and it's
included. When we do this in PHP there are two functions we need to talk about:
include() and require(). The difference between these two functions is subtle but
important, so let's take a closer look. The require()
function works in a XSSI-like way; files
are included as part of the original document as soon as that file is parsed,
regardless of its location in the script. So if you decide to place a require() function inside a conditional loop, the external file will be
included even if that part of the conditional loop is false.
The include() function imports the referenced file each time it is encountered.
If it's not encountered, PHP won't bother with it. This means that you can use include in loops and conditional statements, and they'll work exactly as
planned.
Finally,
if you use require() and the file you're including
does not exist, your script will halt and produce an error. If you use include(), your script will generate a warning, but carry on. You can test
this yourself by trying the following script. Run the script, then replace include() with require() and
compare the results.
<html>
<body>
<?php
include("emptyfile.inc");
echo "Hello
World";
?>
</body>
</html>
I like
to use the suffix .inc with my include files so I can separate them from normal
PHP scripts. If you do this, make sure that you set your Web server
configuration file to parse .inc files as PHP files. Otherwise, hackers might
be able to guess the name of your include files and display them through the
browser as text files. This could be bad if you've got sensitive information -
such as database passwords - contained in the includes.
So what
are you going to do with include files? Simple! Place information common to all
pages inside them. Things like HTML headers, footers, database connection code,
and user-defined functions are all good candidates. Paste this text into a file
called header.inc.
<?php
$db =
mysql_connect("localhost", "root");
mysql_select_db("mydb",$db);
?>
<html>
<head>
<title>
<?php echo
$title ?>
</title>
</head>
<body>
<center><h2><?php
echo $title ?></h2></center>
Then create
another file called footer.txt that contains some appropriate closing text and
tags.
Now
let's create a third file containing the actual PHP script. Try the following
code, making sure that your MySQL server is running.
<?php
$title =
"Hello World";
include("header.inc");
$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</tr>\n", $myrow[1], $myrow[2], $myrow[3]);
}
echo
"</table>\n";
include("footer.inc");
?>
See
what happens? The include files are tossed into the main file and then the
whole thing is executed by PHP. Notice how the variable $title was defined before header.inc is referenced. Its value is made
available to the code in header.inc; hence, the title of the page is changed.
You can now use header.inc across all your PHP pages, and all you'll have to do
is change the value of $title from
page to page.
Using a
combination of includes, HTML, conditional statements, and loops, you can
create complex variations from page to page with an absolute minimum of code.
Includes become especially useful when used with functions, as we'll see down
the road.
On to
the exciting world of data 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. What to do? Time to validate.
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
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.
A more complex function would be ereg(), which uses full regular expression handling for complex queries. I won't delve into the complexities of regex here, as entire books have been written on the subject, but I will provide some examples on the next page.
Let's start with a simple example. We'll check to see whether a variable does or does not exist.
<html>
<body>
<?php
if ($submit) {
if (!$first || !$last) {
$error = "Sorry! You didn't fill in all the fields!";
} else {
// process form
echo "Thank You!";
}
}
if (!$submit || $error) {
echo $error;
?>
<P>
<form method="post" action="<?php echo $PHP_SELF ?>">
FIELD 1: <input type="text" name="first" value="<?php echo $first ?>"><br>
FIELD 2: <input type="text" name="last" value="<?php echo $last ?>"><br>
<input type="Submit" name="submit" value="Enter Information">
</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 statement to
say, "If $first does not exist or $last does not exist, then set $error to
the following." Next, let's extend things a little by checking to see whether a string is a certain length. This would be ideal for passwords, since you don't want some lazy user entering a password of only one or two letters. You'd rather it be, say, six or more characters.
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) {
if (strlen($first) < 6 || strlen($last) < 6) {
$error = "Sorry! You didn't fill in all the fields!";
} else {
// process form
echo "Thank You!";
}
}
if (!$submit || $error) {
echo $error;
?>
<P>
<form method="post" action="<?php echo $PHP_SELF ?>">
FIELD 1: <input type="text" name="first" value="<?php echo $first ?>"><br>
FIELD 2: <input type="text" name="last" value="<?php echo $last ?>"><br>
<input type="Submit" name="submit" value="Enter Information">
</form>
<?php
} // end if
?>
</body>
</html>
Run this script and
try entering six or fewer letters to see what happens. It's simple yet quite
effective.
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.
Using
regular expressions, you can examine a string and intelligently search for
patterns and variations to see whether they match the criteria you set. The
most common of these involves checking whether an email address is valid
(although, of course, there's no fail-safe way of doing this).
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:
if (!ereg("[a-Z]", $first) || !ereg("[a-Z]",
$last)) {
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.
Functions
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.
Functions in PHP behave similarly to functions in C. When we
define the functions, we must specify what values the function can expect to
receive. It's tricky to get a handle on at first, but it prevents weird things
from happening down the road. This is done because the variables inside a
function are known as private variables. That is, they exist only inside the
function. You may, for instance, have a variable in your script called $myname. If you created a function and expected to use the same $myname variable (with the same value), it wouldn't work. Alternatively,
you could have the variable $myname in
your script and also create another variable called $myname in your function, and the two would co-exist quite happily with
separate values. I do not recommend doing this, however! When you come back and
edit it six months later, you'll be breaking things left and right. There are
exceptions to this rule as with all things, but that's outside the scope of
this article.
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>
<body>
<?php
function addnum($first,
$second) {
$newnum = $first +
$second;
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 "Hmm, looks like there was a problem
here...<br>";
echo "The
reported error was $error.\n<br>";
echo "Best you
get hold of the site admin and let her know.";
die;
}
if (!$db = @mysql_connect("localhost","user",
"password")) {
$db_error =
"Could not connect to MySQL Server";
do_error($db_error);
}
?>
</body>
</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;
}
$sql = "SELECT * FROM mytable";
$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.
Confused? For example, when you connect to a database, you nearly
always connect to the same server and you'll likely use the same username and
password. But sometimes you'll need to connect to a different database. Let's
take a look.
<html>
<body>
<?php
function db_connect($host =
"localhost", $user="username", $pass="graeme") {
$db =
mysql_connect($host, $username, $password);
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.
Now all that's left to do is to impart some words of wisdom.
When
it comes to data basing, there's a lot to learn. If you haven't done it
already, find a good book about database design and learn to put together a solid
database - on any platform. It's an invaluable skill and it will save you
plenty of time and headache in the long run. Also, learn about MySQL. It's a
complex but interesting database with a wealth of useful documentation. Learn
about table structure, data types, and SQL. You can actually achieve some
pretty impressive stuff if you know enough SQL. Finally, there's PHP. The PHP Web site has nearly everything you need, from a comprehensive manual to mailing-list archives to code repositories. An excellent way to learn about PHP is to study the examples used in the manual and to check out the code archives. Many of the posted scripts consist of functions or classes that you can use for free in your own scripts without having to reinvent the wheel. Additionally, the mailing list is an excellent spot to check out if you get stuck. The developers themselves read the list and there are plenty of knowledgeable people there who can help you along the way.
Escaping
from HTML
When
PHP starts to handle file, it will just output the text it encounters. So if
you have a HTML-file, and you change its extension to .php, your file will keep
working. If you want to insert php-statements at some point in your file, you'll need to indicate so to php, by entering "PHP mode" in either of the following ways:
Ways of escaping from HTML
1. <? echo ("this is the simplest, an SGML processing instruction\n"); ?>
<?= expression ?> This is a shortcut for "<? echo expression ?>"
2. <?php echo("if you want to serve XHTML or XML documents, do like this\n"); ?>
3. <script language="php">
echo ("some editors (like FrontPage) don't like processing instructions");
</script>
4. <% echo ("You may optionally use ASP-style tags"); %>
<%= $variable; # This is a shortcut for "<%echo .." %>
The
first way is only available if short tags have been enabled. This can be done
by enabling the short open tag configuration setting in the PHP config file, or
by compiling PHP with the --enable-short-tags option to configure. The second way is the generally preferred method, as it allows for the next generation of XHTML to be easily implemented with PHP.
The fourth way is only available if ASP-style tags have been enabled using the asp tags configuration setting.
PHP allows you to use structures like this:
Advanced escaping
<?php
if (boolean-expression) {
?>
<strong>This is true.</strong>
<?php
} else {
?>
<strong>This is false.</strong>
<?php
}
?>
Instructions
are separated the same as in C or Perl - terminate each statement with a
semicolon.
The
closing tag (?>) also implies the end of the statement, so the following are
equivalent:
echo "This is a test";
?>
<?php echo "This is a
test" ?>
PHP
supports eight primitive types. Four scalar types:
·
boolean
·
integer
·
floating-point
number
·
string
Two
compound types:
·
array
·
object
And
finally two special types:
·
resource
·
Null
Note: In this manual
you'll often find mixed
parameters. This pseudo-type indicates multiple possiblities for that
parameter. The type of a variable is usually not set by the programmer; rather, it is decided at runtime by PHP depending on the context in which that variable is used.
This is the easiest type. A Boolean expresses a truth value. It can be either TRUE or FALSE.
Note: The boolean type was introduced in PHP 4.
To specify a boolean literal, use either the keyword TRUE or FALSE. Both are case-insensitive.
$foo = True; // assign the value TRUE to $fooAn integer is a number of the set Z = {..., -2, -1, 0, 1, 2, ...}.
Integers can be specified in decimal (10-based), hexadecimal (16-based) or octal (8-based) notation, optionally preceded by a sign (- or +).
If you use the octal notation, you must precede the number with a 0 (zero), to use hexadecimal notation precede the number with 0x.
Integer literals
$a = 1234; # decimal number
$a = -123; # a negative number
$a = 0123; # octal number (equivalent to 83 decimal)
$a = 0x1A; # hexadecimal number (equivalent to 26 decimal)
The
size of an integer is platform-dependent, although a maximum value of about two
billion is the usual value (that's 32 bits signed). PHP does not support
unsigned integers.
Floating
point numbers (AKA "floats", "doubles" or "real
numbers") can be specified using any of the following syntaxes:
$a = 1.234; $a = 1.2e3; $a = 7E-10;
The size
of a float is platform-dependent, although a maximum of ~1.8e308 with a
precision of roughly 14 decimal digits is a common value (that's 64 bit IEEE
format).
A
string is series of characters. In PHP, a character is the same as a byte, that
is, there are exactly 256 different characters possible. This also implies that
PHP has no native support of Unicode. Note: It is no problem for a string to become very large. There is no practical bound to the size of strings imposed by PHP, so there is no reason at all to worry about long strings.
A string literal can be specified in three different ways.
·
Single
quoted
·
Double
quoted
·
Heredoc
syntax
Single quoted
The easiest way to specify a simple string is to enclose it in single quotes (the character ').To specify a literal single quote, you will need to escape it with a backslash (\), like in many other languages. If a backslash needs to occur before a single quote or at the end of the string, you need to double it. Note that if you try to escape any other character, the backslash too will be printed! So usually there is no need to escape the backslash itself.
Note: In PHP 3, a warning will be issued at the E_NOTICE level when this happens.
Note: Unlike the two other syntaxes, variables will not be expanded when they occur in single quoted strings.
echo 'this is a simple string';
echo 'You can also have embedded newlines in strings,
like this way.';
echo 'Arnold once said: "I\'ll be back"';
// output: ... "I'll be back"
echo 'Are you sure you want to delete C:\\*.*?';
// output: ... delete C:\*.*?
echo 'Are you sure you want to delete C:\*.*?';
// output: ... delete C:\*.*?
echo 'I am trying to include at this point: \n a newline';
// output: ... this point: \n a newline
Double quoted
If the string is enclosed in double-quotes ("), PHP understands more escape sequences for special characters:Table 6-1. Escaped characters
Sequence
|
Meaning
|
\n
|
linefeed (LF or
0x0A (10) in ASCII)
|
\r
|
carriage return
(CR or 0x0D (13) in ASCII)
|
\t
|
horizontal tab
(HT or 0x09 (9) in ASCII)
|
\\
|
Backslash
|
\$
|
dollar sign
|
\"
|
double-quote
|
\[0-7]{1,3}
|
the sequence of
characters matching the regular expression is a character in octal notation
|
\x[0-9A-Fa-f]{1,2}
|
the sequence of
characters matching the regular expression is a character in hexadecimal
notation
|
Some string examples
<?php
/* Assigning a string. */
$str = "This is a string";
/* Appending to it. */
$str = $str . " with some more text";
/* Another way to append, includes an escaped newline. */
$str .= " and a newline at the end.\n";
/* This string will end up being '<p>Number: 9</p>' */
$num = 9;
$str = "<p>Number: $num</p>";
/* This one will be '<p>Number: $num</p>' */
$num = 9;
$str = '<p>Number: $num</p>';
/* Get the first character of a string */
$str = 'This is a test.';
$first = $str{0};
/* Get the last character of a string. */
$str = 'This is still a test.';
$last = $str{strlen($str)-1};
?>
$foo = 1 + "10.5"; // $foo is float (11.5)
$foo = 1 + "-1.3e3"; // $foo is float (-1299)
$foo = 1 + "bob-1.3e3"; // $foo is integer (1)
$foo = 1 + "bob3"; // $foo is integer (1)
$foo = 1 + "10 Small Pigs"; // $foo is integer (11)
$foo = 1 + "10 Little Piggies"; // $foo is integer (11)
$foo = "10.0 pigs " + 1; // $foo is integer (11)
$foo = "10.0 pigs " + 1.0; // $foo is float (11)
For
more information on this conversion, see the Unix manual page for strtod(3). If you would like to test any of the examples in this section, you can cut and paste the examples and insert the following line to see for yourself what's going on:
echo "\$foo==$foo; type is " . gettype ($foo) . "<br>\n"; |
An array in PHP is actually an ordered map. A map is a type that maps values to keys. This type is optimized in several ways, so you can use it as a real array, or a list (vector), hashtable (which is an implementation of a map), dictionary, collection, stack, queue and probably more. Because you can have another PHP-array as a value, you can also quite easily simulate trees.
Specifying with array()
An
array can be created by the array language-construct. It takes a certain number
of comma-separated key => value
pairs. A key is either a nonnegative integer or a string. If a key is the standard representation of a non-negative integer, it will be interpreted as such (i.e. '8' will be interpreted as 8, while '08' will be interpreted as '08').
A value can be anything.
Omitting keys.
If you omit a key, the maximum of the integer-indices is taken, and the new key will be that maximum + 1. If no integer-indices exist yet, the key will be 0 (zero). If you specify a key that already has a value assigned to it, that value will be overwritten.
array( [key =>] value
, ...
)
// key is either string or nonnegative integer
// value can be anything
You
can also modify an existing array, by explicitly setting values. This is done by assigning values to the array while specifying the key in brackets. You can also omit the key, add an empty pair of brackets ("[]") to the variable-name in that case.
$arr[key] = value;
$arr[] = value;
// key is either string or nonnegative integer
// value can be anythingIf $arr doesn't exist yet, it will be created. So this is also an alternative way to specify an array. To change a certain value, just assign a new value to it. If you want to remove a key/value pair, you need to unset() it.
The foreach control structure exists specificly for arrays. It provides an easy way to traverse an array.
You might have seen the following syntax in old scripts:
$foo[bar] = 'enemy';
echo $foo[bar];
// etc
This
is wrong, but it works. Then, why is it wrong? The reason is that, as stated in
the syntax section, there must be an
expression between the square brackets ('['
and ']'). That means that
you can write things like this:
echo $arr[ foo(true) ];
This
is an example of using a function return value as the array index. PHP knows
also about constants, and you may have seen the E_*
before.
$error_descriptions[E_ERROR] = "A fatal error has occured";
$error_descriptions[E_WARNING] = "PHP issued a warning";
$error_descriptions[E_NOTICE] = "This is just an informal notice";
Note
that E_ERROR
is also a valid identifier, just like bar
in the first example. But the last example is in fact the same as writing:
$error_descriptions[1] = "A fatal error has occured";
$error_descriptions[2] = "PHP issued a warning";
$error_descriptions[8] = "This is just an informal notice";
because
E_ERROR equals 1,
etc.
Then,
how is it possible that $foo[bar]
works? It works, because bar is due to its
syntax expected to be a constant expression. However, in this case no constant
with the name bar exists. PHP now
assumes that you meant bar literally, as the
string "bar",
but that you forgot to write the quotes. The array type in PHP is very versatile, so here will be some examples to show you the full power of arrays.
// this
$a = array( 'color' => 'red'
, 'taste' => 'sweet'
, 'shape' => 'round'
, 'name' => 'apple'
, 4 // key will be 0
);
// is completely equivalent with
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name'] = 'apple';
$a[] = 4; // key will be 0
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// will result in the array array( 0 => 'a' , 1 => 'b' , 2 => 'c' ),
// or simply array('a', 'b', 'c')
Using
array()// Array as (property-)map
$map = array( 'version' => 4
, 'OS' => 'Linux'
, 'lang' => 'english'
, 'short_tags' => true
);
// strictly numerical keys
$array = array( 7
, 8
, 0
, 156
, -10
);
// this is the same as array( 0 => 7, 1 => 8, ...)
$switching = array( 10 // key = 0
, 5 => 6
, 3 => 7
, 'a' => 4
, 11 // key = 6 (maximum of integer-indices was 5)
, '8' => 2 // key = 8 (integer!)
, '02' => 77 // key = '02'
, 0 => 12 // the value 10 will be overwritten by 12
);
// empty array
$empty = array();
$colors = array('red','blue','green','yellow');
foreach ( $colors as $color ) {
echo "Do you like $color?\n";
}
/* output:
Do you like red?
Do you like blue?
Do you like green?
Do you like yellow?
*/
Collection
foreach( $colors as $key => $color ) {
// won't work:
//$color = strtoupper($color);
//works:
$colors[$key] = strtouuper($color);
}
print_r($colors);
/* output:
Array
(
[0] => RED
[1] => BLUE
[2] => GREEN
[3] => YELLOW
)
*/
This
example creates a one-based array. One-based index
$firstquarter = array(1 => 'January', 'February', 'March');
print_r($firstquarter);
/* output:
Array
(
[1] => 'January'
[2] => 'February'
[3] => 'March'
)
*/
// fill an array with all items from a directory
$handle = opendir('.');
while ($file = readdir($handle))
{
$files[] = $file;
}
closedir($handle);
]Objects
To initialize an object, you use the new statement to instantiate the object to a variable.
<?php
class foo
{
function do_foo()
{
echo "Doing foo.";
}
}
$bar = new foo;
$bar->do_foo();
?>
The
special NULL
value represents that a variable has no value. NULL
is the only possible value of type NULL. Note: The null type was introduced in PHP 4
There is only one value of type NULL, and that is the case-insensitive keyword NULL.
$var = Null;
Variables
Variables
in PHP are represented by a dollar sign followed by the name of the variable.
The variable name is case-sensitive. Variable names follow the same rules as other labels in PHP. A valid variable name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
Note: For our purposes here, a letter is a-z, A-Z, and the ASCII characters from 127 through 255 (0x7f-0xff).
$var = "Bob";
$Var = "Joe";
echo "$var, $Var"; // outputs "Bob, Joe"
$4site = 'not yet'; // invalid; starts with a number
$_4site = 'not yet'; // valid; starts with an underscore
$täyte = 'mansikka'; // valid; 'ä' is ASCII 228.
In
PHP 3, variables are always assigned by value. That is to say, when you assign
an expression to a variable, the entire value of the original expression is
copied into the destination variable. This means, for instance, that after
assigning one variable's value to another, changing one of those variables will
have no effect on the other. For more information on this kind of assignment.PHP 4 offers another way to assign values to variables: assign by reference. This means that the new variable simply references (in other words, "becomes an alias for" or "points to") the original variable. Changes to the new variable affect the original, and vice versa. This also means that no copying is performed; thus, the assignment happens more quickly. However, any speedup will likely be noticed only in tight loops or when assigning large arrays or objects.
To assign by reference, simply prepend an ampersand (&) to the beginning of the variable which is being assigned (the source variable). For instance, the following code snippet outputs 'My name is Bob' twice:
<?php
$foo = 'Bob'; // Assign the value 'Bob' to $foo
$bar = &$foo; // Reference $foo via $bar.
$bar = "My name is $bar"; // Alter $bar...
echo $foo; // $foo is altered too.
echo $bar;
?>
One
important thing to note is that only named variables may be assigned by
reference. <?php
$foo = 25;
$bar = &$foo; // This is a valid assignment.
$bar = &(24 * 7); // Invalid; references an unnamed expression.
function test()
{
return 25;
}
$bar = &test(); // Invalid.
?>
PHP
provides a large number of predefined variables to any script which it runs.
Many of these variables, however, cannot be fully documented as they are
dependent upon which server is running, the version and setup of the server,
and other factors. Some of these variables will not be available when PHP is
run on the command-line. Despite these factors, here is a list of predefined variables available under a stock installation of PHP 3 running as a module under a stock installation of Apache1.3.6.
For a list of all predefined variables (and lots of other useful information), please see (and use) phpinfo().
Note: This list is neither exhaustive nor intended to be. It is simply a guideline as to what sorts of predefined variables you can expect to have access to in your script.
These
variables are created by the Apache webserver. If you are running another
webserver, there is no guarantee that it will provide the same variables; it
may omit some, or provide others not listed here. That said, a large number of
these variables are accounted for in the CGI 1.1 specification, so you should
be able to expect those.
Note
that few, if any, of these will be available (or indeed have any meaning) if
running PHP on the command line.
$GATEWAY_INTERFACE
What
revision of the CGI specification the server is using; i.e. 'CGI/1.1'.
$SERVER_NAME
The
name of the server host under which the current script is executing. If the
script is running on a virtual host, this will be the value defined for that
virtual host.
$SERVER_SOFTWARE
Server
identification string, given in the headers when responding to requests.
$SERVER_PROTOCOL
Name
and revision of the information protocol via which the page was requested; i.e.
'HTTP/1.0';
$REQUEST_METHOD
Which
request method was used to access the page; i.e. 'GET', 'HEAD', 'POST', 'PUT'.
$QUERY_STRING
The
query string, if any, via which the page was accessed.
$DOCUMENT_ROOT
The
document root directory under which the current script is executing, as defined
in the server's configuration file.
$HTTP_ACCEPT
Contents
of the Accept:
header from the current request, if there is one.
$HTTP_ACCEPT_CHARSET
Contents
of the Accept-Charset:
header from the current request, if there is one. Example:
'iso-8859-1,*,utf-8'.
$HTTP_ACCEPT_ENCODING
Contents
of the Accept-Encoding:
header from the current request, if there is one. Example: 'gzip'.
$HTTP_ACCEPT_LANGUAGE
Contents
of the Accept-Language:
header from the current request, if there is one. Example: 'en'.
$HTTP_CONNECTION
Contents
of the Connection:
header from the current request, if there is one. Example: 'Keep-Alive'.
$HTTP_HOST
Contents
of the Host:
header from the current request, if there is one.
$HTTP_REFERER
The
address of the page (if any) which referred the browser to the current page.
This is set by the user's browser; not all browsers will set this.
$HTTP_USER_AGENT
Contents
of the User_Agent:
header from the current request, if there is one. This is a string denoting the
browser software being used to view the current page; i.e. Mozilla/4.5
[en] (X11; U; Linux 2.2.9 i586).
Among other things, you can use this value with get_browser()to tailor
your page's functionality to the capabilities of the user's browser.
$REMOTE_ADDR
The
IP address from which the user is viewing the current page.
$REMOTE_PORT
The
port being used on the user's machine to communicate with the web server.
$SCRIPT_FILENAME
The
absolute pathname of the currently executing script.
$SERVER_ADMIN
The
value given to the SERVER_ADMIN (for Apache) directive in the web server
configuration file. If the script is running on a virtual host, this will be
the value defined for that virtual host.
$SERVER_PORT
The
port on the server machine being used by the web server for communication. For
default setups, this will be '80'; using SSL, for instance, will change this to
whatever your defined secure HTTP port is.
$SERVER_SIGNATURE
String
containing the server version and virtual host name which are added to
server-generated pages, if enabled.
$PATH_TRANSLATED
Filesystem-
(not document root-) based path to the current script, after the server has
done any virtual-to-real mapping.
$SCRIPT_NAME
Contains
the current script's path. This is useful for pages which need to point to
themselves.
$REQUEST_URI
The
URI which was given in order to access this page; for instance, '/index.html'.
Environment variables
These variables are imported into PHP's global namespace from the environment under which the PHP parser is running. Many are provided by the shell under which PHP is running and different systems are likely running different kinds of shells, a definitive list is impossible. Please see your shell's documentation for a list of defined environment variables.
Other environment variables include the CGI variables, placed there regardless of whether PHP is running as a server module or CGI processor.
These variables are created by PHP itself. The $HTTP_*_VARS variables are available only if the track_vars configuration is turned on. When enabled, the variables are always set, even if they are empty arrays. This prevents a malicious user from spoofing these variables.
Note: As of PHP 4.0.3, track_vars is always turned on, regardless of the configuration file setting.
If the register_globals directive is set, then these variables will also be made available in the global scope of the script; i.e., separate from the $HTTP_*_VARS arrays. This feature should be used with care, and turned off if possible; while the $HTTP_*_VARS variables are safe, the bare global equivalents can be overwritten by user input, with possibly malicious intent. If you cannot turn off register_globals, you must take whatever steps are necessary to ensure that the data you are using is safe.
$argv
Array
of arguments passed to the script. When the script is run on the command line,
this gives C-style access to the command line parameters. When called via the
GET method, this will contain the query string.
$argc
Contains
the number of command line parameters passed to the script (if run on the
command line).
$PHP_SELF
The
filename of the currently executing script, relative to the document root. If
PHP is running as a command-line processor, this variable is not available.
$HTTP_COOKIE_VARS
An
associative array of variables passed to the current script via HTTP cookies.
$HTTP_GET_VARS
An
associative array of variables passed to the current script via the HTTP GET
method.
$HTTP_POST_VARS
An
associative array of variables passed to the current script via the HTTP POST
method.
$HTTP_POST_FILES
An
associative array of variables containing information about files uploaded via
the HTTP POST method. See POST method uploads for information on the contents
of $HTTP_POST_FILES.
$HTTP_POST_FILES
is available only in PHP 4.0.0 and later.
$HTTP_ENV_VARS
An
associative array of variables passed to the current script via the parent
environment.
$HTTP_SERVER_VARS
An
associative array of variables passed to the current script from the HTTP
server. These variables are analogous to the Apache variables described above.
The
scope of a variable is the context within which it is defined. For the most
part all PHP variables only have a single scope. This single scope spans
included and required files as well. For example:
include "b.inc";
Here the
$a
variable will be available within the included b.inc script. However, within
user-defined functions a local function scope is introduced. Any variable used
inside a function is by default limited to the local function scope. For
example:
function Test()
{
echo $a; /* reference to local scope variable */
}
Test();
This
script will not produce any output because the echo statement refers to a local
version of the $a
variable, and it has not been assigned a value within this scope. You may
notice that this is a little bit different from the C language in that global
variables in C are automatically available to functions unless specifically
overridden by a local definition. This can cause some problems in that people
may inadvertently change a global variable. In PHP global variables must be
declared global inside a function if they are going to be used in that
function. An example:
$b = 2;
function Sum()
{
global $a, $b;
$b = $a + $b;
}
Sum();
echo $b;
The
above script will output "3". By declaring $a
and $b global within the function, all
references to either variable will refer to the global version. There is no
limit to the number of global variables that can be manipulated by a function.
A second
way to access variables from the global scope is to use the special PHP-defined
$GLOBALS array.
The previous example can be rewritten as:
$b = 2;
function Sum()
{
$GLOBALS["b"] = $GLOBALS["a"] + $GLOBALS["b"];
}
Sum();
echo $b;
The $GLOBALS array
is an associative array with the name of the global variable being the key and
the contents of that variable being the value of the array element.
Another
important feature of variable scoping is the static variable. A static
variable exists only in a local function scope, but it does not lose its value
when program execution leaves this scope. Consider the following example:
{
$a = 0;
echo $a;
$a++;
}
This
function is quite useless since every time it is called it sets $a
to 0 and prints "0". The $a++ which increments the variable
serves no purpose since as soon as the function exits the $a variable disappears. To make a
useful counting function which will not lose track of the current count, the $a variable is declared static:
{
static $a = 0;
echo $a;
$a++;
}
Now,
every time the Test() function is called it will print the value of $a and increment it.
Static
variables also provide one way to deal with recursive functions. A recursive
function is one which calls itself. Care must be taken when writing a recursive
function because it is possible to make it recurse indefinitely. You must make
sure you have an adequate way of terminating the recursion. The following
simple function recursively counts to 10, using the static variable $count to know when to stop:
{
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
Test ();
}
$count--;
}
Variable variables
Sometimes
it is convenient to be able to have variable variable names. That is, a
variable name which can be set and used dynamically. A normal variable is set
with a statement such as:
A
variable variable takes the value of a variable and treats that as the name of
a variable. In the above example, hello, can be used as the name of a
variable by using two dollar signs. i.e.
At this
point two variables have been defined and stored in the PHP symbol tree: $a with contents "hello"
and $hello with
contents "world". Therefore, this statement:
produces
the exact same output as:
i.e.
they both produce: hello
world.
In order
to use variable variables with arrays, you have to resolve an ambiguity
problem. That is, if you write $$a[1] then
the parser needs to know if you meant to use $a[1] as a variable, or if you wanted
$$a as the
variable and then the [1] index from that variable. The syntax for resolving
this ambiguity is: ${$a[1]} for the
first case and ${$a}[1] for the
second.
When a form is submitted to a PHP script, any variables from that form will be automatically made available to the script by PHP. If the track_vars configuration option is turned on, then these variables will be located in the associative arrays $HTTP_POST_VARS, $HTTP_GET_VARS, and/or $HTTP_POST_FILES, according to the source of the variable in question.
For more information on these variables, please read Predefined variables.
Example 7-1. Simple form variable
<form action="foo.php" method="post">
Name: <input type="text" name="username"><br>
<input type="submit">
</form>
When
the above form is submitted, the value from the text input will be available in
$HTTP_POST_VARS['username'].
If the register_globals configuration directive is turned on, then the variable
will also be available as $username
in the global scope. Note: The magic_quotes_gpc configuration directive affects Get, Post and Cookie values. If turned on, value (It's "PHP!") will automagically become (It\'s \"PHP!\"). Escaping is needed for DB insertion. Also see addslashes(), stripslashes() and magic_quotes_sybase.
PHP also understands arrays in the context of form variables. You may, for example, group related variables together, or use this feature to retrieve values from a multiple select input:
Example 7-2. More complex form variables
<form action="array.php" method="post">
Name: <input type="text" name="personal[name]"><br>
Email: <input type="text" name="personal[email]"><br>
Beer: <br>
<select multiple name="beer[]">
<option value="warthog">Warthog
<option value="guinness">Guinness
<option value="stuttgarter">Stuttgarter Schwabenbräu
</select>
<input type="submit">
</form>
In
PHP 3, the array form variable usage is limited to single-dimensional arrays.
In PHP 4, no such restriction applies. IMAGE SUBMIT variable names
When submitting a form, it is possible to use an image instead of the standard submit button with a tag like:<input type="image" src="image.gif" name="sub">When the user clicks somewhere on the image, the accompanying form will be transmitted to the server with two additional variables, sub_x and sub_y. These contain the coordinates of the user click within the image. The experienced may note that the actual variable names sent by the browser contains a period rather than an underscore, but PHP converts the period to an underscore automatically.
PHP transparently supports HTTP cookies as defined by Netscape's Spec. Cookies are a mechanism for storing data in the remote browser and thus tracking or identifying return users. You can set cookies using the setcookie() function. Cookies are part of the HTTP header, so the SetCookie function must be called before any output is sent to the browser. This is the same restriction as for the header() function. Any cookies sent to you from the client will automatically be turned into a PHP variable just like GET and POST method data.
If you wish to assign multiple values to a single cookie, just add [] to the cookie name. For example:
setcookie("MyCookie[]", "Testing", time()+3600);Note that a cookie will replace a previous cookie by the same name in your browser unless the path or domain is different. So, for a shopping cart application you may want to keep a counter and pass this along. i.e.
SetCookie Example
$Count++;
setcookie("Count", $Count, time()+3600);
setcookie("Cart[$Count]", $item, time()+3600);
PHP
automatically makes environment variables available as normal PHP variables. echo $HOME; /* Shows the HOME environment variable, if set. */Since information coming in via GET, POST and Cookie mechanisms also automatically create PHP variables, it is sometimes best to explicitly read a variable from the environment in order to make sure that you are getting the right version. The getenv() function can be used for this. You can also set an environment variable with the putenv() function.
Dots in incoming variable names
Typically, PHP does not alter the names of variables when they are passed into a script. However, it should be noted that the dot (period, full stop) is not a valid character in a PHP variable name. For the reason, look at it:$varname.ext; /* invalid variable name */
Now,
what the parser sees is a variable named $varname,
followed by the string concatenation operator, followed by the barestring (i.e.
unquoted string which doesn't match any known key or reserved words) 'ext'.
Obviously, this doesn't have the intended result. For this reason, it is important to note that PHP will automatically replace any dots in incoming variable names with underscores.
Because PHP determines the types of variables and converts them (generally) as needed, it is not always obvious what type a given variable is at any one time. PHP includes several functions which find out what type a variable is. They are gettype(), is_long(), is_double(), is_string(), is_array(), and is_object().
Constants
A constant is a identifier (name) for a simple value. As the name suggests, that value cannot change during the execution of the script (the magic constants __FILE__ and __LINE__ are the only exception). A constant is case-sensitive by default. By convention constants are always uppercase.
The name of a constant follows the same rules as any label in PHP. A valid constant name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
Note: For our purposes here, a letter is a-z, A-Z, and the ASCII characters from 127 through 255 (0x7f-0xff).
The scope of a constant is global.
Defining Constants
<?php
define("CONSTANT", "Hello world.");
echo CONSTANT; // outputs "Hello world."
echo Constant; // outputs "Constant" and issues a notice.
?>
Predefined constants
The
predefined constants (always available) are:
__FILE__
(case-insensitive)
The
name of the script file presently being parsed. If used within a file which has
been included or required, then the name of the included file is given, and not
the name of the parent file.
__LINE__
(case-insensitive)
The
number of the line within the current script file which is being parsed. If
used within a file which has been included or required, then the position
within the included file is given.
PHP_VERSION
The
string representation of the version of the PHP parser presently in use; for
example '4.1.0'.
PHP_OS
The
name of the operating system on which the PHP parser is executing;. Possible
values may be : "AIX", "Darwin" (MacOS), "Linux",
"SunOS", "WIN32", "WINNT". Note: other values may
be available too.
TRUE
(case-insensitive)
A
TRUE
value (see the boolean type).
FALSE
(case-insensitive)
A
FALSE
value (see the boolean type).
NULL
(case-insensitive)
A
NULL
value (see the null type).
E_ERROR
Denotes
an error other than a parsing error from which recovery is not possible.
E_WARNING
Denotes
a condition where PHP knows something is wrong, but will continue anyway; these
can be caught by the script itself. An example would be an invalid regexp in ereg().
E_PARSE
The
parser choked on invalid syntax in the script file. Recovery is not possible.
E_NOTICE
Something
happened which may or may not be an error. Execution continues. Examples
include using an unquoted string as an array index, or accessing a variable
which has not been set.
E_ALL
All
of the E_* constants rolled into one. If used with error_reporting(),
will cause any and all problems noticed by PHP to be reported.
The
E_* constants are
typically used with the error_reporting() function for setting the error
reporting level. See all these constants at Error handling. Using __FILE__ and __LINE__
<?php
function report_error($file, $line, $message)
{
echo "An error occured in $file on line $line: $message.";
}
report_error(__FILE__, __LINE__, "Something went wrong!");
?>
Example
|
Name
|
Result
|
$a == $b
|
Equal
|
TRUE if $a is
equal to $b.
|
$a === $b
|
Identical
|
TRUE if $a is
equal to $b, and they are of the same type. (PHP 4 only)
|
$a != $b
|
Not equal
|
TRUE if $a is not
equal to $b.
|
$a <> $b
|
Not equal
|
TRUE if $a is not
equal to $b.
|
$a !== $b
|
Not identical
|
TRUE if $a is not
equal to $b, or they are not of the same type. (PHP 4 only)
|
$a < $b
|
Less than
|
TRUE if $a is
strictly less than $b.
|
$a > $b
|
Greater than
|
TRUE if $a is
strictly greater than $b.
|
$a <= $b
|
Less than or equal to
|
TRUE if $a is less
than or equal to $b.
|
$a >= $b
|
Greater than or equal to
|
TRUE if $a is
greater than or equal to $b.
|
Another
conditional operator is the "?:" (or ternary) operator, which
operates as in C and many other languages.
This
expression evaluates to expr2 if expr1 evaluates
to TRUE, and expr3 if expr1
evaluates to FALSE.
Error Control Operators
PHP supports one error control operator: the at sign (@). When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored.
If the track_errors feature is enabled, any error message generated by the expression will be saved in the global variable $php_errormsg. This variable will be overwritten on each error, so check early if you want to use it.
<?php
/* Intentional file error */
$my_file = @file ('non_existent_file') or
die ("Failed opening file: error was '$php_errormsg'");
// this works for any expression, not just functions:
$value = @$cache[$key];
// will not issue a notice if the index $key doesn't exist.
?>
Note: The @-operator
works only on expressions. A simple rule of thumb is: if you can take the value
of something, you can prepend the @ operator to it. For instance, you can
prepend it to variables, function and include() calls, constants, and so
forth. You cannot prepend it to function or class definitions, or conditional
structures such as if and foreach,
and so forth.
Warning
|
Currently the "@" error-control operator prefix will even disable error reporting for critical errors that will terminate script execution. Among other things, this means that if you use "@" to suppress errors from a certain function and either it isn't available or has been mistyped, the script will die right there with no indication as to why. |
Execution Operators
PHP supports one execution operator: backticks (``). Note that these are not single-quotes! PHP will attempt to execute the contents of the backticks as a shell command; the output will be returned (i.e., it won't simply be dumped to output; it can be assigned to a variable).
$output = `ls -al`;
echo "<pre>$output</pre>";
Note: The backtick
operator is disabled when safe mode is enabled. See also system(), passthru(), exec(), popen(), and escapeshellcmd().
Table 10-5. Logical Operators
Example
|
Name
|
Result
|
$a and $b
|
And
|
TRUE
if both $a and $b are TRUE.
|
$a or $b
|
Or
|
TRUE
if either $a or $b is TRUE.
|
$a xor $b
|
Xor
|
TRUE
if either $a or $b is TRUE,
but not both.
|
! $a
|
Not
|
TRUE
if $a is not TRUE.
|
$a && $b
|
And
|
TRUE
if both $a and $b are TRUE.
|
$a || $b
|
Or
|
TRUE
if either $a or $b is TRUE.
|
$a = "Hello "; $b = $a . "World!"; // now $b contains "Hello World!"
$a = "Hello ";
$a .= "World!"; // now $a contains "Hello World!"
|
Alternative syntax for control structures
PHP offers an alternative syntax for some of its control structures; namely, if, while, for, foreach, and switch. In each case, the basic form of the alternate syntax is to change the opening brace to a colon (:) and the closing brace to endif;, endwhile;, endfor;, endforeach;, or endswitch;, respectively.<?php if ($a == 5): ?> A is equal to 5
<?php endif; ?>
|
The alternative syntax applies to else and elseif as well. The following is an if structure with elseif and else in the alternative format:
if ($a == 5): print "a equals 5";
print "...";
elseif ($a == 6):
print "a equals 6";
print "!!!";
else:
print "a is neither 5 nor 6";
endif;
|
foreach
PHP 4 (not PHP 3) includes a foreach construct, much like Perl and some other languages. This simply gives an easy way to iterate over arrays. There are two syntaxes; the second is a minor but useful extension of the first:foreach(array_expression as $value) statement foreach(array_expression as $key => $value) statement
|
The second form does the same thing, except that the current element's key will be assigned to the variable $key on each loop.
Note: When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array. This means that you do not need to call reset() before a foreach loop.
Note: Also note that foreach operates on a copy of the specified array, not the array itself, therefore the array pointer is not modified as with the each() construct and changes to the array element returned are not reflected in the original array.
Note: foreach does not support the ability to suppress error messages using '@'.
You may have noticed that the following are functionally identical:
reset ($arr); while (list(, $value) = each ($arr)) {
echo "Value: $value<br>\n";
}
foreach ($arr as $value) {
echo "Value: $value<br>\n";
}
|
The
following are also functionally identical:
reset ($arr); while (list($key, $value) = each ($arr)) {
echo "Key: $key; Value: $value<br>\n";
}
foreach ($arr as $key => $value) {
echo "Key: $key; Value: $value<br>\n";
}
|
declare
The declare construct is used to set execution directives for a block of code. The syntax of declare is similiar to the syntax of other flow control constructs:declare (directive) statement |
The statement part of the declare block will be executed - how it is executed and what side-effects occur during execution may depend on the directive set in the directive block.
Ticks
A tick is an event that occurs for every N low-level statements executed by the parser within the declare block. The value for N is specified using ticks=N within the declare blocks's directive section.The event(s) that occurs on each tick is specified using the register_tick_function(). See the example below for more details. Note that more than one event can occur for each tick.
The example profiles the PHP code within the 'declare' block, recording the time at which every second low-level statement in the block was executed. This information can then be used to find the slow areas within particular segments of code. This process can be performed using other methods: using ticks is more convenient and easier to implement.
Ticks are well suited for debugging, implementing simple multitasking, backgrounded I/O and many other tasks.
See also register_tick_function() and unregister_tick_function().
require()
The require() statement replaces itself with the specified file, much like the C preprocessor's #include works.If "URL open wrappers" are enabled in PHP (which they are in the default configuration), you can specify the file to be require()ed using an URL instead of a local pathname.
An important note about how this works is that when a file is include()ed or require()ed, parsing drops out of PHP mode and into HTML mode at the beginning of the target file, and resumes PHP mode again at the end. For this reason, any code inside the target file which should be executed as PHP code must be enclosed within valid PHP start and end tags.
require() is not actually a function in PHP; rather, it is a language construct. It is subject to some different rules than functions are. For instance, require() is not subject to any containing control structures. For another, it does not return any value; attempting to read a return value from a require() call results in a parse error.
Unlike include(), require() will always read in the target file, even if the line it's on never executes. If you want to conditionally include a file, use include(). The conditional statement won't affect the require(). However, if the line on which the require() occurs is not executed, neither will any of the code in the target file be executed.
Similarly, looping structures do not affect the behaviour of require(). Although the code contained in the target file is still subject to the loop, the require() itself happens only once.
This means that you can't put a require() statement inside of a loop structure and expect it to include the contents of a different file on each iteration. To do that, use an include() statement.
require ('header.inc'); |
If the require()ed file is called via HTTP using the fopen wrappers, and if the target server interprets the target file as PHP code, variables may be passed to the require()ed file using an URL request string as used with HTTP GET. This is not strictly speaking the same thing as require()ing the file and having it inherit the parent file's variable scope; the script is actually being run on the remote server and the result is then being included into the local script.
/* This example assumes that someserver is configured to parse .php * files and not .txt files. Also, 'works' here means that the variables
* $varone and $vartwo are available within the require()ed file. */
/* Won't work; file.txt wasn't handled by someserver. */
require ("http://someserver/file.txt?varone=1&vartwo=2");
/* Won't work; looks for a file named 'file.php?varone=1&vartwo=2'
* on the local filesystem. */
require ("file.php?varone=1&vartwo=2");
/* Works. */
require ("http://someserver/file.php?varone=1&vartwo=2");
$varone = 1;
$vartwo = 2;
require ("file.txt"); /* Works. */
require ("file.php"); /* Works. */
|
include()The include() statement includes and evaluates the specified file.If "URL open wrappers" are enabled in PHP (which they are in the default configuration), you can specify the file to be include()ed using an URL instead of a local pathname. An important note about how this works is that when a file is include()ed or require()ed, parsing drops out of PHP mode and into HTML mode at the beginning of the target file, and resumes again at the end. For this reason, any code inside the target file which should be executed as PHP code must be enclosed within valid PHP start and end tags. This happens each time the include() statement is encountered, so you can use an include() statement within a looping structure to include a number of different files.
Because include() is a special language construct, you must enclose it within a statement block if it is inside a conditional block.
If the include()ed file is called via HTTP using the fopen wrappers, and if the target server interprets the target file as PHP code, variables may be passed to the include()ed file using an URL request string as used with HTTP GET. This is not strictly speaking the same thing as include()ing the file and having it inherit the parent file's variable scope; the script is actually being run on the remote server and the result is then being included into the local script.
|
require_once()
The require_once() statement replaces itself with the specified file, much like the C preprocessor's #include works, and in that respect is similar to the require() statement. The main difference is that in an inclusion chain, the use of require_once() will assure that the code is added to your script only once, and avoid clashes with variable values or function names that can happen.For example, if you create the following 2 include files utils.inc and foolib.inc
utils.inc
|
foolib.inc
|
cause_error_require.php
|
GLOBALS ARE NICE GLOBALS ARE NICE
Fatal error: Cannot redeclare goodTea() in utils.inc on line 5
|
By
modifying foolib.inc
and cause_errror_require.php
to use require_once() instead of require() and renaming the last
one to avoid_error_require_once.php,
we have:
foolib.inc
(fixed)
|
avoid_error_require_once.php
|
And
when running the latter, the output will be (using PHP 4.0.1pl2):
GLOBALS ARE NICE this is requiring globals.inc again which is also
required in foolib.inc
Running goodTea: Oolong tea tastes good!
Printing foo:
Array
(
[0] => 1
[1] => Array
(
[0] => complex
[1] => quaternion
)
)
|
include_once()
The include_once() statement includes and evaluates the specified file during the execution of the script. This is a behavior similar to the include() statement, with the important difference that if the code from a file has already been included, it will not be included again.As mentioned in the require_once() description, the include_once() should be used in the cases in which the same file might be included and evaluated more than once during a particular execution of a script, and you want to be sure that it is included exactly once to avoid problems with function redefinitions, variable value reassignments, etc.
For more examples on using require_once() and include_once(), look at the PEAR code included in the latest PHP source code distributions.
Functions
A function may be defined using syntax such as the following:function foo ($arg_1, $arg_2, ..., $arg_n) {
echo "Example function.\n";
return $retval;
}
|
In PHP 3, functions must be defined before they are referenced. No such requirement exists in PHP 4.
PHP does not support function overloading, nor is it possible to undefine or redefine previously-declared functions.
PHP 3 does not support variable numbers of arguments to functions, although default arguments are supported.
Comments
Post a Comment