Everything I Know About PHP

(a very short document)

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:
<?php echo "$SiteOwner's Daily News\n"; ?>
<?php echo "<H1>News for " . date("M/D/Y") . "</H1>\n"; ?>
<P>Welcome! This paragraph will never change...</P>

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.,
$cGlobalInfo = 1337;   function MakeFoo() {
    $cOnlyInFoo = "This is only in function MakeFoo";
    echo "Value of the global is $cGlobalInfo";     return 0;
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:
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
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!"
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:
... 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.

Peter B. Steiger
Cinco de Mayo 2008