Two weeks ago my wife asked me to find her a program that will let her post book reviews on her website so all her teeming fans can read her critiques. I didn't find anything suitable, but I learned that the latest fad for online databases is a combination of the php programming language and the MySQL database query language. In fact, those two items make up half of the popular "LAMP" stack (Linux, Apache, MySQL, PHP) for web servers.
I'm not a patient person, so when I had a question about php that was not answered on the php.net documentation site (most questions are covered there), I would go to a realtime chat channel to ask my question. Last night, I got my answer in about 30 seconds and then spent the next two hours answering OTHER new users who just happened to ask about stuff I had recently learned how to do myself.
So... for my friends who want to know how to use php, and for anyone else who has the delusion that I have some knowledge on the subject worth sharing, here's a quick guide to getting started in php.
The server: Your web hosting provider must have php installed on their end, and their web server software must have the option set to allow it to run php programs. Otherwise, if someone pulls up your php page, they won't get the web page you designed - instead, they will see the raw programming code you used to create the site. Kinda like opening your TV guide and seeing a schematic of the TV antenna instead of reading the program listings.
File Names: use the dot-extension .php or .phtml for your web pages that incorporate php. If you use .htm or .html, the server will simply dump the raw contents of that file on-screen (see above) rather than execute the program file as instructions.
Php and HTML can be freely intermixed, so you can use plain HTML
for the parts that never change and php for the parts that need to
be modified on-the-fly while a user is visiting your site. For example:
<HTML>
<HEAD>
<TITLE>
<?php echo "$SiteOwner's Daily News\n"; ?>
</TITLE>
</HEAD>
<BODY>
<?php echo "<H1>News for " . date("M/D/Y") . "</H1>\n"; ?>
<P>Welcome! This paragraph will never change...</P>
</BODY>
</HTML>
A couple of things to notice here: All php code is surrounded within
the <?php and ?> brackets. This is true even if the entire program
is all php from start to finish. Also notice that each php command ends
with a semicolon. That's so you can spread a lengthy php command across
multiple lines, and the parser only makes sense of the whole thing when
it gets to the semicolon - just like Pascal or C. If you wanted, you
could have just one gigantic <?php and ?> pair as the first and
last lines, respectively, of the entire .php file. But that would mean
every line of actual HTML output would have to use the print or echo
commands - e.g., echo "<TITLE>My Title</TITLE>.
Let's talk about variables. In php, all variables begin with the
dollar sign. Why? I don't know, but I forget about half the time
and half to go back and fix them when my program blows up. Names are
also case-sensitive, so $foo and $Foo are two different items (take
it from me, that's a really bad thing to do). And finally, php is
"loose typed", which means a given variable can be declared at any
point in the program, is not assigned a specific data type, and can
in fact change type whenever it strikes your fancy - e.g.,
<?php $foo = 1337; $foo = "Leet"; ?>
Variables can be of global scope if they are declared at the beginning
of the program - meaning their value is known by any functions called
by the first program both within and without that .php file. They can
also be local if defined within the boundaries of a function - e.g.,
<?php
$cGlobalInfo = 1337;
function MakeFoo() {
$cOnlyInFoo = "This is only in function MakeFoo";
echo "Value of the global is $cGlobalInfo";
return 0;
}
MakeFoo();
echo "The local variable contains $cOnlyInFoo";
echo "The global variable contains $cGlobalInfo";
?>
This will print out an empty value for the variable because $cOnlyInFoo only
contains data while it is within the local function MakeFoo(). But the
global variable $cGlobalInfo will print out the number 1337 in both places,
because that value was declared early and is available to any subsequent
references. Good programming practice says you should NOT use global
variables like this, because you don't know if or where they were set.
Oh, I should mention quotes. Php lets you surround text with single
quotes (apostrophes) or double quotes ("). There is a difference!
Single quotes will not expand variable names or escaped constants like
\n (end-of-line); instead they will print out as the variable name or
escaped constant name. So this:
echo 'I, $StateYourName, do hereby swear\n';
will actually print the name "$StateYourName" and the escape
character \n. If you use double quotes, it will correctly fill in with
the value for $StateYourName and it will translate \n into a line break.
Single quotes are useful for printing the actual quote symbol:
echo 'This "phrase" contains printed "quotation marks"';
Getting back to variables, how about a list of data types? Even though typing is not enforced, you can treat different types of data differently. You have strings, which is anything in quotes; integers, which is any number that does not have a decimal in the explicit value given or in any resulting calculations, and floating point (floats), which are numeric values that do carry a decimal value. Php will automatically convert types from one to another if you mix them together in a statement - hence "Fred" + 5 will result in the integer value 5, because "Fred" is converted to its integer value - which is zero because it contains no actual numbers - and added to 5. On the other paw, "5"+"5" would produce 55, combining the quoted text strings "5" and "5" together. To paraphrase Calvin, charactering weirds integers.
And let's not forget arrays! Arrays are subscripted with square
brackets. The cool thing about php arrays is you can use text OR
integer subscripts:
$Family['Mother'] = "Wilma"
$Family['Father'] = "Fred"
$Family[3] = "Pebbles"
Which brings us to as good a place as any to discuss the operators
that let you combine data. Integers and floats use all the standard
operators +, -, /, and * as well as the modulus operator % (which
gives the remainder of a division, such as 17 % 4 yields 1). Text
strings are normally concatenanted with the dot operator (.), even
though the plus sign seems to work on most versions of php. For
compatibility, you should use dot instead:
$Greeting = 'Hello, my name is "' . $StateYourName . '"';
See how I put the double quotes, which I want printed as part of
the string, inside single quotes? Since I was using single quotes
I could not have $StateYourName automatically expand into the actual
name within the quotes like you can with double quotes, so I used the
dot operator to concatenate the three parts of the sentence.
The one other thing I want to mention about operators is the shortcut
of operator-equal. Instead of writing A = A * B, you can write A *= B.
That works with all the math operators and even the dot operator:
$WishList = "I want peace on earth";
$Wishlist .= " and a pony";
Oh, and of course there is the boolean comparison operator ==. That
examines two items and returns TRUE if they are identical (well, technically
it returns the integer value 1 if they match and 0 if they do not, but
php like most languages of the C generation uses zero and FALSE interchangeably,
and nonzero or TRUE). Funny thing, php will let you use an assignment
equal sign as a condition:
if ($Name = "Fred")
Will always be true, because it first stuffs the variable Name with the
text Fred, and then checks to see if $Name is equal to "Fred"
So be careful when you write an equal comparison in an IF statement, or
you might end up storing the wrong values to the wrong variables!
Also note that strings can succeed in an == match if the first part of
the string contains an integer that matches the numeric part on the
other side. That is,
if ("1337 Hax0rz" == 1337)
... will return true, because it automatically converts the string
"1337 Hax0rz" to the integer value 1337, which does indeed
match the numeric 1337 on the right side of the equation. If you want
to be triple-sure that both the data type and values match, you can
use the triple-equal comparison:
if ("1337 Hax0rz" === 1337)
... returns FALSE because the string is not the same data type as the
integer.
Getting data from the user
Have you ever wondered what happens to the stuff you type in on
data entry forms? It turns out the web page reloads itself, sending
itself (or a new page, if you used a different target) the contents
of that form. If you have <FORM METHOD=POST TARGET="_self">
and then within the form <INPUT TYPE=text NAME=StateYourName> it will
wait for you to click on the submit button, then because you used the
target _self it will reload itself. The result is that when you are
using php to process form results within the same .php file that lets
the user type in those form answers, you need to use an if condition
to decide "Has the user clicked submit yet? If so, I need to process
the input. If not, I need to present the input form." So...
if ( isset($_POST['StateYourName']) ) {
echo "Thank you for your input, $_POST['StateYourName']!\n"
} else {
echo "<FORM METHOD=POST TARGET=_self>\n";
echo "<INPUT TYPE=text NAME=StateYourName>\n"
echo "<INPUT TYPE=submit NAME=submit VALUE=submit>\n"
}
That in and of itself is enough for a complete, albeit simple, web
page. The first time the page is loaded, the POST variable StateYourName
is not set so the if statement evaluates as false, leading control to
the ELSE clause that draws the form and accepts input. The second time
the page loads, after you click the submit button, POST['StateYourName']
does contain a value so the first part of the IF statement executes,
printing the greeting, and the form itself is not redrawn. If that sounds
too complicated, you could change TARGET to some other web page that
is specifically designed to process the input.
A few other concepts were introduced above. First is the global
array $_POST. When use use the POST method (vs. GET, which we will
get to in a minute), php creates an array called $_POST that uses the
NAME= part of each INPUT form element as the text index to that array
element - so in our example above, the $_POST array would have the
contents $_POST['StateYourName'] and $_POST['submit'].
You also see the use of a typical IF block. Like C, multi-line responses
to an IF decision must be surrounded by curly braces, although if you
only need one thing to happen you can omit the braces - in the above
example, I could have left the braces off the echo "Thank you..."
line because it was the only action dependent on that decision. But the
ELSE clause did require braces because it was the condition for the
next three statements together.
Finally, notice the use of the \n in some places. This has no effect
on program output or operation! You would echo "<BR>"
to cause the page the user sees to skip to to the next line. \n just
makes the generated source code easier to read if you use "View Source"
from your browser. HTML doesn't care if you bunch the entire web page
from <HTML> to </HTML> into one six hundred mile long line
or break it up, so that's really only useful as a debugging tool. Leaving
the line breaks off also makes it more difficult for nosy people to use
View Source to read how your page was designed and copy all your favorite
tricks for their own page - but of course, even then View Source will
only show them the HTML that resulted from all the php behind-the-scenes
activity, so they won't be able to see your php source files. If I
filled in the form in the above example and hit submit, then used View
Source, I would see a normal-looking HTML file with the one line
Hello, Peter!
If my buddy Janie Bob visits the same site, puts in her name, and
submits the form and then uses View Source, she would see nothing
but: Hello, Janie Bob!
The POST statement in a user form is not the only way to pass
data around among different parts of your .php file or multiple
.php files. You can use the GET method in a form, which instead
of populating the $_POST[] array will instead transmit the user's
response as part of the URL when it reloads. So if I instead said
METHOD=GET above, and the user clicked submit, the result would be
for the web page foobar.php to reload itself and you would see in
the URL at the top: foobar.php?StateYourName=Janie Bob
If there are multiple form fields like City and State, they are
added to the URL with an ampersand:
foobar.php?StateYourName=Peter&City=Cheyenne&State=WY
Items transmitted by way of the URL are collected in another
global array called $_GET... and you guessed it, the array
subscripts are the variable names from the URL. So in the
above example, you can access $_GET['StateYourName'],
$_GET['City'], and $_GET['State']. Note that this is an insecure
way of transmitting data, because as Mr. Evil Pirate your user
can stuff desired values into the URL and bypass the form entirely.
Sometimes this is useful, if you WANT your users to be able to
give their own URL or link from outside, like
sellstuff.php?Category=Books&Subject=php
But you would not want private data transmitted via the GET
array on the URL, and you would not want to give the user control
(by artificially stuffing the URL) of anything that should be
secure. Imagine if you went through all the trouble of prompting
for a password, testing the password against valid passwords, and
upon success passing control over to a members-only page... if you
sent them to the URL membersonly.php?validPW=yes ... they could
just type that URL in manually, including the "validPW=yes"
part, and let themselves in to your secure site!
Which brings us to two other methods for transmitting data
around to different parts of your application: cookies and session
variables. I don't like cookies because they rely too much on
whether the user has enabled cookies in his or her browser, so if
you want to use cookies you will need to visit php.net and read
about them yourself. I will probably add some later so repeat
visitors can save their preferences, but for now I just use
the session array to store data.
That's the global array called $_SESSION[], and again it uses
named offsets into the array that you can set and unset at will,
such as $_SESSION['validPW'] = TRUE; . The user has no way to
add or modify data in the $_SESSION[] array; it can only be
programmed from within by php statements. So, for example, if
the user has put in a valid password and I do some magic with
the if statement and some SQL database lookups, I can say
$_SESSION['validPW'] = TRUE;
The $_SESSION[] array is globally accessible, so I can go right
over to secure.php and say:
if ( $_SESSION['validPW'] )
echo "Welcome, friend!"
else
echo "Get lost, stranger!"
The trick to using the $_SESSION array is that you have to
open a pipeline to it in any .php program that will make use of
it, with the session_start() command. That's all you do, put that
one line at the top of your .php script (inside the <?php header
of course) in all your .php files, and they can all access the same
values from the same $_SESSION array. The contents of the array can
be erased by direct command:
unset($_SESSION['validPW']);
... or by way of the session_destroy() function. If you do not
manually remove those values or call session_destroy(), they will
be destroyed automatically after the user breaks the connection with
your website - with a short "grace period". You have probably
seen how you can log in to a site, set some preferences, then close your
browser but come back just a few seconds later, and your preferences are
still set. That isn't necessarily cookies working their magic, it
could also be session values that have not expired yet. For this
reason, you should always provide a logout mechanism that triggers
the session_destroy() function if you are storing secure or private
data, so I can't walk up behind someone who closes the browser, open
it back up, and go straight back to their website and still have
access to their session variables.
Rinse, lather, and repeat:
One last thing I should touch on is iteration. If you have ever
written any program in any language in your life, you know about
the FOR..NEXT loop. The one in php follows the C standard, which is:
for ($variable initial setting; loop close condition; $variable increment)
the statements that follow should be in curly braces if there are more than
one, but again you can omit the braces if only a single action occurs during
the loop. For example:
for ($i = 1; i <= 10; i++) {
echo "If I told you once, I have told you $i times<BR>";
}
The WHILE loop works the same way except you set the initialization
before the loop starts and the exit condition can change any way you
want during the loop. This is good for times when you don't have an
exact number of iterations, but need to repeat until some non-numeric
event occurs:
$PlayAgain = TRUE;
while ( $PlayAgain ) {
// do some stuff to play a game
// fetch input asking if the user wants to play again
if ($_POST['OneMoTime'] == "No")
$PlayAgain = FALSE;
}
Finally, there's the foreach() function, which lets you loop through
the contents of an array:
foreach( $_POST as $i ) {
echo "The input field name is: $i and the value is: ". $_POST["$i"];
}
If the POST array from an input form contains Name, Age, and Rank this loop
would print three lines, each one saying the field name (Name, Age, and then
Rank) followed by the value the user had typed into each of those fields.
And much, much more...
That's just the proverbial tip of the iceberg, but you can write a pretty
nifty website that processes input forms just with what you gathered here.
I can't stress enough the importance of the official php documentation
site, php.net. Visit there to read all
the built-in functions I left out, all about interfacing with a SQL
database query, and who-knows-what all else.