Introduction to PHP
Introduction
PHP (recursive acronym for PHP: Hypertext Preprocessor) is a free scripting language primarily used to produce dynamic web pages via an HTTP server, but it can also function like any interpreted language locally by executing programs on the command line. PHP is an imperative language that has had complete object-oriented model capabilities since version 5. Due to the richness of its library, PHP is sometimes referred to as a platform rather than just a language.
Basics
- In pages containing mainly HTML, it is possible to insert small pieces of PHP to make life easier. Just use tags like:
<html>
<head>
<title>PHP says hello</title>
</head>
<body>
<b>
<?php
print "Hello, World!";
?>
</b>
</body>
</html>
This will produce:
<html>
<head><title>PHP says hello</title></head>
<body>
<b>
Hello, World!
</b>
</body>
</html>
- We can also reverse the example above to put HTML code in a PHP page:
<?php
print <<<_HTML_
<form method="post" action="$_SERVER[PHP_SELF]">
Your Name: <input type="text" name="user">
<br/>
<input type="submit" value="Say Hello">
</form>
_HTML_;
?>
The $_SERVER[PHP_SELF]
variable is special to PHP. It is used to get the URL of the called link but without the protocol or the hostname. For example:
https://www.deimos.fr/blocnotesinfo/index.php?title=Introduction_au_PHP
Only what is in bold is kept.
To give you an idea of what’s available, you can create a file with this:
<?php
echo "<table border=\"1\">";
echo "<tr><td>" .$_SERVER['argv'] ."</td><td>argv</td></tr>";
echo "<tr><td>" .$_SERVER['argc'] ."</td><td>argc</td></tr>";
echo "<tr><td>" .$_SERVER['GATEWAY_INTERFACE'] ."</td><td>GATEWAY_INTERFACE</td></tr>";
echo "<tr><td>" .$_SERVER['SERVER_ADDR'] ."</td><td>SERVER_ADDR</td></tr>";
echo "<tr><td>" .$_SERVER['SERVER_NAME'] ."</td><td>SERVER_NAME</td></tr>";
echo "<tr><td>" .$_SERVER['SERVER_SOFTWARE'] ."</td><td>SERVER_SOFTWARE</td></tr>";
echo "<tr><td>" .$_SERVER['SERVER_PROTOCOL'] ."</td><td>SERVER_PROTOCOL</td></tr>";
echo "<tr><td>" .$_SERVER['REQUEST_METHOD'] ."</td><td>REQUEST_METHOD</td></tr>";
echo "<tr><td>" .$_SERVER['REQUEST_TIME'] ."</td><td>REQUEST_TIME</td></tr>";
echo "<tr><td>" .$_SERVER['QUERY_STRING'] ."</td><td>QUERY_STRING</td></tr>";
echo "<tr><td>" .$_SERVER['DOCUMENT_ROOT'] ."</td><td>DOCUMENT_ROOT</td></tr>";
echo "<tr><td>" .$_SERVER['HTTP_ACCEPT'] ."</td><td>HTTP_ACCEPT</td></tr>";
echo "<tr><td>" .$_SERVER['HTTP_ACCEPT_CHARSET'] ."</td><td>HTTP_ACCEPT_CHARSET</td></tr>";
echo "<tr><td>" .$_SERVER['HTTP_ACCEPT_ENCODING'] ."</td><td>HTTP_ACCEPT_ENCODING</td></tr>";
echo "<tr><td>" .$_SERVER['HTTP_ACCEPT_LANGUAGE'] ."</td><td>HTTP_ACCEPT_LANGUAGE</td></tr>";
echo "<tr><td>" .$_SERVER['HTTP_CONNECTION'] ."</td><td>HTTP_CONNECTION</td></tr>";
echo "<tr><td>" .$_SERVER['HTTP_HOST'] ."</td><td>HTTP_HOST</td></tr>";
echo "<tr><td>" .$_SERVER['HTTP_REFERER'] ."</td><td>HTTP_REFERER</td></tr>";
echo "<tr><td>" .$_SERVER['HTTP_USER_AGENT'] ."</td><td>HTTP_USER_AGENT</td></tr>";
echo "<tr><td>" .$_SERVER['HTTPS'] ."</td><td>HTTPS</td></tr>";
echo "<tr><td>" .$_SERVER['REMOTE_ADDR'] ."</td><td>REMOTE_ADDR</td></tr>";
echo "<tr><td>" .$_SERVER['REMOTE_HOST'] ."</td><td>REMOTE_HOST</td></tr>";
echo "<tr><td>" .$_SERVER['REMOTE_PORT'] ."</td><td>REMOTE_PORT</td></tr>";
echo "<tr><td>" .$_SERVER['SCRIPT_FILENAME'] ."</td><td>SCRIPT_FILENAME</td></tr>";
echo "<tr><td>" .$_SERVER['SERVER_ADMIN'] ."</td><td>SERVER_ADMIN</td></tr>";
echo "<tr><td>" .$_SERVER['SERVER_PORT'] ."</td><td>SERVER_PORT</td></tr>";
echo "<tr><td>" .$_SERVER['SERVER_SIGNATURE'] ."</td><td>SERVER_SIGNATURE</td></tr>";
echo "<tr><td>" .$_SERVER['PATH_TRANSLATED'] ."</td><td>PATH_TRANSLATED</td></tr>";
echo "<tr><td>" .$_SERVER['SCRIPT_NAME'] ."</td><td>SCRIPT_NAME</td></tr>";
echo "<tr><td>" .$_SERVER['REQUEST_URI'] ."</td><td>REQUEST_URI</td></tr>";
echo "<tr><td>" .$_SERVER['PHP_AUTH_DIGEST'] ."</td><td>PHP_AUTH_DIGEST</td></tr>";
echo "<tr><td>" .$_SERVER['PHP_AUTH_USER'] ."</td><td>PHP_AUTH_USER</td></tr>";
echo "<tr><td>" .$_SERVER['PHP_AUTH_PW'] ."</td><td>PHP_AUTH_PW</td></tr>";
echo "<tr><td>" .$_SERVER['AUTH_TYPE'] ."</td><td>AUTH_TYPE</td></tr>";
echo "</table>"
?>
- For HTML forms corresponding to this:
<form method="POST" action="sayhello.php">
Your Name: <input type="text" name="user">
<br/>
<input type="submit" value="Say Hello">
</form>
This will produce in PHP:
<?php
print "Hello, ";
// Print what was submitted in the form parameter called 'user'
print $_POST['user'];
print "!";
?>
$_POST contains the values of the form parameters as they were submitted. In programming terms, it’s a variable named as such because you can modify the values it contains. In fact, it’s a array variable because it can hold multiple values simultaneously.
When $_SERVER[PHP_SELF] is the form’s action, you can place both the form display code and the form processing code on the same page:
<?php
// Print a greeting if the form was submitted
if ($_POST['user']) {
print "Hello, ";
// Print what was submitted in the form parameter called 'user'
print $_POST['user'];
print "!";
} else {
// Otherwise, print the form
print <<<_HTML_
<form method="post" action="$_SERVER[PHP_SELF]">
Your Name: <input type="text" name="user">
<br/>
<input type="submit" value="Say Hello">
</form>
_HTML_;
}
?>
For comments, you can use:
//
: For a single line to comment/* to */
: To comment a paragraph, we will come back to this later.
Now here is an example of PHP code that connects to a database server and retrieves a list of dishes with their prices based on the value of the “rpas” parameter, then displays these dishes and their prices in an HTML table:
<?php
require 'DB.php';
// Connect to MySQL running on localhost with username "menu"
// and password "good2eaT", and database "dinner"
$db = DB::connect('mysql://menu:good2eaT@localhost/dinner');
// Define what the allowable meals are
$meals = array('breakfast','lunch','dinner');
// Check if submitted form parameter "meal" is one of
// "breakfast", "lunch", or "dinner"
if (in_array($meals, $_POST['meal'])) {
// If so, get all of the dishes for the specified meal
$q = $dbh->query("SELECT dish,price FROM meals WHERE meal LIKE '" .
$_POST['meal'] ."'");
// If no dishes were found in the database, say so
if ($q->numrows == 0) {
print "No dishes available.";
} else {
// Otherwise, print out each dish and its price as a row
// in an HTML table
print '<table><tr><th>Dish</th><th>Price</th></tr>';
while ($row = $q->fetchRow( )) {
print "<tr><td>$row[0]</td><td>$row[1]</td></tr>";
}
print "</table>";
}
} else {
// This message prints if the submitted parameter "meal" isn't
// "breakfast", "lunch", or "dinner"
print "Unknown meal.";
}
?>
Manipulation of textual and numerical data
Strings can be delimited by “”. They work like strings surrounded by ‘, but allow more special characters:
Character | Meaning |
---|---|
\n | Newline (ASCII 10) |
\r | Carriage return (ASCII 13) |
\t | Tab (ASCII 9) |
\ | \ |
$ | $ |
" | " |
\0 .. \777 | Octal (base 8) number |
\x0 .. \xFF | Hexadecimal (base 16) number |
A small example to clarify everything. Imagine $user is Pierre:
- ‘Hello $user’: Will display: Hello $user
- “Hello $user”: Will display: Hello Pierre
To combine 2 strings, use a “.” which allows concatenation of strings:
print 'bread' . 'fruit';
print "It's a beautiful day " . 'in the neighborhood.';
print "The price is: " . '$3.95';
print 'Inky' . 'Pinky' . 'Blinky' . 'Clyde';
This will display:
breadfruit
It's a beautiful day in the neighborhood.
The price is: $3.95
InkyPinkyBlinkyClyde
Text manipulation
String validation
The trim() function removes spaces at the beginning or end of a string. Combined with strlen(), which tells you the length of a string, you can know the length of a value submitted by a form while ignoring leading and trailing spaces.
// $_POST['zipcode'] holds the value of the submitted form parameter
// "zipcode"
$zipcode = trim($_POST['zipcode']);
// Now $zipcode holds that value, with any leading or trailing spaces
// removed
$zip_length = strlen($zipcode);
// Complain if the ZIP code is not 5 characters long
if ($zip_length != 5) {
print "Please enter a ZIP code that is 5 characters long.";
}
You can do it shorter by combining functions. Similar to Final Fantasy when you combine mana:
if (strlen(trim($_POST['zipcode'])) != 5) {
print "Please enter a ZIP code that is 5 characters long.";
}
To compare strings with the equality operator, use (==):
if ($_POST['email'] == 'president@whitehouse.gov') {
print "Welcome, Mr. President.";
}
To compare strings without taking case into account, use the strcasecmp() function. It returns 0 if the 2 strings provided to strcasecmp() are equal (regardless of case):
if (strcasecmp($_POST['email'], 'president@whitehouse.gov') == 0) {
print "Welcome back, Mr. President.";
}
Text formatting
printf() gives more control than print over the output appearance:
$price = 5; $tax = 0.075;
printf('The dish costs $%.2f', $price * (1 + $tax));
This will display:
The dish costs $5.38
The “%.2f” is replaced by the value of $price * (1 + $tax)) and formatted to have 2 digits after the decimal point.
Format rules start with %. You can then place optional modifiers that affect the rule’s behavior:
- A fill character: If the string replacing the format rule is too short, this character will fill it. Use a space to fill with spaces or a 0 to fill with zeros.
- A sign: For numbers, a + will place a + before positive numbers (they are normally displayed without a sign). For strings, a - will make the string right-justified (by default, strings are left-justified).
- A minimum width: the minimum size that the value replacing the format rule should have. If it’s shorter, the fill character will be used to fill the void.
- A point and a number of decimal places: For floating point numbers, this controls the number of digits after the decimal point. In the example above, the .2 formats $price * (1 + $tax)); with 2 decimal places.
Here’s an example of zero-padding with printf():
$zip = '6520';
$month = 2;
$day = 6;
$year = 2007;
printf("ZIP is %05d and the date is %02d/%02d/%d", $zip, $month, $day, $year);
Will display:
ZIP is 06520 and the date is 02/06/2007
Displaying signs with printf():
$min = -40;
$max = 40;
printf("The computer can operate between %+d and %+d degrees Celsius.", $min, $max);
Will display:
The computer can operate between -40 and +40 degrees Celsius.
To discover other rules with printf, visit http://www.php.net
The functions strtolower() and strtoupper() produce, respectively, all lowercase or all uppercase versions of a string.
print strtolower('Beef, CHICKEN, Pork, duCK');
print strtoupper('Beef, CHICKEN, Pork, duCK');
Will display:
beef, chicken, pork, duck
BEEF, CHICKEN, PORK, DUCK
The function ucwords() capitalizes the first letter of each word in a string:
print ucwords(strtolower('JOHN FRANKENHEIMER'));
Will display:
John Frankenheimer
Truncating a string with substr():
// Grab the first thirty characters of $_POST['comments']
print substr($_POST['comments'], 0, 30);
// Add an ellipsis
print '...';
Will display:
The Fresh Fish with Rice Noodle was delicious, but I didn't like the Beef Tripe.
The three parameters of substr() are respectively, the string concerned, the starting position of the substring to extract and the number of characters to extract. The string starts at position 0, not 1: substr($_POST[‘comments’], 0, 30) therefore means “extract 30 characters from $_POST[‘comments’] starting from the beginning of this string”.
Extracting the end of a string with substr():
print 'Card: XX';
print substr($_POST['card'],-4,4);
If the form parameter is worth 4000-1234-5678-9101, this will display:
Card: XX9101
So this is a very practical example for credit cards.
For brevity, you can use substr($_POST[‘card’],-4) instead of substr($_POST[‘card’], -4,4). If you don’t provide the last parameter, substr() will return everything between the starting position (whether positive or negative) and the end of the string.
Using str_replace():
print str_replace('{class}',$my_class,
'<span class="{class}">Fried Bean Curd<span>
<span class="{class}">Oil-Soaked Fish</span>');
Will display:
<span class="lunch">Fried Bean Curd<span>
<span class="lunch">Oil-Soaked Fish</span>
Arithmetic operators
Some basic operations in PHP:
print 2 + 2;
print 17 - 3.5;
print 10 / 3;
print 6 * 9;
Will display:
4
13.5
3.3333333333333
54
In addition to the +, -, /, and * signs, PHP has the modulo % which returns the remainder of a division:
print 17 % 3;
will display:
2
Variables
Here are examples of acceptable variables:
$size
$drinkSize
$my_drink_size
$_drinks
$drink4you2
And unacceptable:
Variable name | Flaw |
---|---|
Begins with a number | $2hot4u |
Unacceptable character: - | $drink-size |
Unacceptable characters: @ and . | $drinkmaster@example.com |
Unacceptable character:! | $drink!lots |
Unacceptable character: + | $drink+dinner |
Variable names are case sensitive!!!
Operations on variables
Some operations on variables:
<?php
$price = 3.95;
$tax_rate = 0.08;
$tax_amount = $price * $tax_rate;
$total_cost = $price + $tax_amount;
$username = 'james';
$domain = '@example.com';
$email_address = $username . $domain;
print 'The tax is ' . $tax_amount;
print "\n"; // this prints a linebreak
print 'The total cost is ' .$total_cost;
print "\n"; // this prints a linebreak
print $email_address;
?>
Addition combined with assignment:
// Add 3 the regular way
$price = $price + 3;
// Add 3 with the combined operator
$price += 3;
Incrementation and decrementation:
// Add one to $birthday
$birthday = $birthday + 1;
// Add another one to $birthday
++$birthday;
// Subtract 1 from $years_left
$years_left = $years_left - 1;
// Subtract another 1 from $years_left
Variables placed in strings
In-place document interpolation:
$page_title = 'Menu';
$meat = 'pork';
$vegetable = 'bean sprout';
print <<<MENU
<html>
<head><title>$page_title</title></head>
<body>
<ul>
<li> Barbecued $meat
<li> Sliced $meat
<li> Braised $meat with $vegetable
</ul>
</body>
</html>
MENU;
Will display:
<html>
<head><title>Menu</title></head>
<body>
<ul>
<li> Barbecued pork
<li> Sliced pork
<li> Braised pork with bean sprout
</ul>
</body>
Interpolation with braces:
$preparation = 'Braise';
$meat = 'Beef';
print "{$preparation}d $meat with Vegetables";
Will display:
Braised Beef with Vegetables
Without the braces, the print instruction in the example above would have been:
print "$preparationd $meat with Vegetables";
Decision making and repetitions
In this chapter, we’ll see how to:
- Display a special menu if a user with admin rights is logged in.
- Display a different page header depending on the time of day.
- Notify a user if they’ve received new messages since their last connection.
When making decisions, the PHP interpreter reduces an expression to a true or false value.
The value of an assignment is the assigned value. The expression $price = 5 equals 5: this price has been assigned to $price. Since assignment produces a result, you can chain assignments to assign the same value to multiple variables:
$price = $quantity = 5;
Decision making
Using elseif():
if ($logged_in) {
// This runs if $logged_in is true
print "Welcome aboard, trusted user.";
} elseif ($new_messages) {
// This runs if $logged_in is false but $new_messages is true
print "Dear stranger, there are new messages.";
} elseif ($emergency) {
// This runs if $logged_in and $new_messages are false
// But $emergency is true
print "Stranger, there are no new messages, but there is an emergency.";
} else {
// You can put what you want
}
Creating complex decisions
The equality operator:
if ($new_messages == 10) {
print "You have ten new messages.";
}
if ($new_messages == $max_messages) {
print "You have the maximum number of messages.";
}
if ($dinner == 'Braised Scallops') {
print "Yum! I love seafood.";
}
The difference operator:
if ($new_messages != 10) {
print "You don't have ten new messages.";
}
if ($dinner != 'Braised Scallops') {
print "I guess we're out of scallops.";
}
Be careful not to use = when you want to use ==. A single equals sign assigns a value and returns the assigned value, while two equal signs test equality and return true if the values are equal. If you forget the second equals sign, you will usually get an if() test that will always be true:
Example of an assignment that should have been a comparison:
if ($new_messages = 12) {
print "It seems you now have twelve new messages.";
}
One way to avoid inadvertently using = instead of == is to place the variable on the right side of the comparison and the literal on the left:
if (12 == $new_messages) {
print "You have twelve new messages.";
}
Less than and greater than operators:
if ($age > 17) {
print "You are old enough to download the movie.";
}
if ($age >= 65) {
print "You are old enough for a discount.";
}
if ($celsius_temp <= 0) {
print "Uh-oh, your pipes may freeze.";
}
if ($kelvin_temp < 20.3) {
print "Your hydrogen is a liquid or a solid now.";
}
Floating-point numbers have an internal representation that may be slightly different from the assigned value (the internal representation of 50.0, for example, might be 50.000000002). To test if 2 floating-point numbers are equal, check if the difference between these 2 numbers is less than a reasonably small threshold, instead of using the equality operator. If you compare monetary values, for example, an acceptable threshold would be 0.00001.
Floating-point number comparisons:
if(abs($price_1 - $price_2) < 0.00001) {
print '$price_1 and $price_2 are equal.';
} else {
print '$price_1 and $price_2 are not equal.';
}
The abs() function returns the absolute value of its parameter. With abs(), the comparison works correctly, whether $price_1 is greater than $price_2 or not.
The ASCII codes for digits are less than those for uppercase letters, which are themselves less than the codes for lowercase letters; the codes for accented letters are in the “extended” part, thus higher than all codes in international ASCII.
Generally, strings are compared alphabetically (caramel < chocolate).
String comparison:
if ($word < 'baa') {
print "Your word isn't cookie.";
}
if ($word >= 'zoo') {
print "Your word could be zoo or zymurgy, but not zone.";
}
If you want to make sure the PHP interpreter compares strings without performing numeric conversion behind the scenes, use the strcmp() function which always compares its parameters according to the ASCII table order.
The strcmp() function takes two strings as parameters. It returns a positive number if the first string is greater than the second or a negative number if the first string is less than the second. The order is that of the extended ASCII table. This function returns 0 if the 2 strings are equal.
String comparisons with strcmp():
$x = strcmp("x54321","x5678");
if ($x > 0) {
print 'The string "x54321" is greater than the string "x5678".';
} elseif ($x < 0) {
print 'The string "x54321" is less than the string "x5678".';
}
In the example below, strcmp() finds that the string “54321” is less than “5678” because the second characters of the 2 strings differ and “4” comes before “6”. The alphabetical order is all that matters to the strcmp() function, no matter that numerically it’s the opposite.
// These values are compared using numeric order
if ("54321" > "5678") {
print 'The string "54321" is greater than the string "5678".';
} else {
print 'The string "54321" is not greater than the string "5678".';
}
Using the negation operator:
if (! strcasecmp($first_name,$last_name)) {
print '$first_name and $last_name are equal.';
}
With logical operators, you can combine multiple expressions in the same if() statement. The logical AND operator, &, tests if 2 expressions are both true. The logical OR operator, ||, tests if at least one of the 2 expressions is true:
if (($age >= 13) && ($age < 65)) {
print "You are too old for a kid's discount and too young for the senior's discount.";
}
if (($meal == 'breakfast') || ($dessert == 'souffle')) {
print "Time to eat some eggs.";
}
Repetitions
Producing a
$i = 1;
print '<select name="people">';
while ($i <= 10) {
print "<option>$i</option>\n";
$i++;
}
print '</select>';
Will display:
<select name="people"><option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
</select>
Producing a
print '<select name="people">';
for ($i = 1; $i <= 10; $i++) {
print "<option>$i</option>";
}
print '</select>';
The third expression ($i++) is the iteration expression. It is executed after each execution of the loop body.
Multiple expressions in for():
print '<select name="doughnuts">';
for ($min = 1, $max = 10; $min < 50; $min += 10, $max += 10) {
print "<option>$min - $max</option>\n";
}
print '</select>';
Using arrays
In the examples that follow, here’s the typical array we’ll be working with:
Creating an array
- Creating arrays:
// An array called $vegetables with string keys
$vegetables['corn'] = 'yellow';
$vegetables['beet'] = 'red';
$vegetables['carrot'] = 'orange';
// An array called $dinner with numeric keys
$dinner[0] = 'Sweet Corn and Asparagus';
$dinner[1] = 'Lemon Chicken';
$dinner[2] = 'Braised Bamboo Fungus';
// An array called $computers with numeric and string keys
$computers['trs-80'] = 'Radio Shack';
$computers[2600] = 'Atari';
$computers['Adam'] = 'Coleco';
Array keys and values are written exactly like other strings and numbers in a PHP program: with apostrophes around strings, but not around numbers.
- Creating arrays with array():
$vegetables = array('corn' => 'yellow',
'beet' => 'red',
'carrot' => 'orange');
$dinner = array(0 => 'Sweet Corn and Asparagus',
1 => 'Lemon Chicken',
2 => 'Braised Bamboo Fungus');
$computers = array('trs-80' => 'Radio Shack',
2600 => 'Atari',
'Adam' => 'Coleco');
With array(), you specify a list of key/value pairs separated by commas. The key and value are separated by =>. The array() syntax is more concise when adding multiple elements to an array at once. The bracket syntax is preferable when adding elements one by one.
Creating an array indexed by numbers
If you create an array with array() by specifying only a list of values instead of key/value pairs, the PHP interpreter automatically assigns a numeric key to each value. The keys start at 0 and increase by 1 for each element. The example below uses this technique to create the $dinner array:
$dinner = array('Sweet Corn and Asparagus',
'Lemon Chicken',
'Braised Bamboo Fungus');
print "I want $dinner[0] and $dinner[1].";
Will display:
I want Sweet Corn and Asparagus and Lemon Chicken.
PHP automatically uses incremented numbers for keys when creating an array or adding elements to an array with the empty brackets syntax:
// Create $lunch array with two elements
// This sets $lunch[0]
$lunch[] = 'Dried Mushrooms in Brown Sauce';
// This sets $lunch[1]
$lunch[] = 'Pineapple and Yu Fungus';
// Create $dinner with three elements
$dinner = array('Sweet Corn and Asparagus', 'Lemon Chicken',
'Braised Bamboo Fungus');
// Add an element to the end of $dinner
// This sets $dinner[3]
$dinner[] = 'Flank Skin with Spiced Flavor';
If the array doesn’t exist yet, empty brackets create it by adding an element with key 0.
Finding the size of an array
The count() function returns the number of elements in an array:
$dinner = array('Sweet Corn and Asparagus',
'Lemon Chicken',
'Braised Bamboo Fungus');
$dishes = count($dinner);
print "There are $dishes things for dinner.";
Will display:
There are 3 things for dinner.
When passed an empty array (i.e., an array containing no elements), count() returns 0. An empty array is also evaluated as false in a test expression.
Traversing arrays
- Traversal with foreach():
$meal = array('breakfast' => 'Walnut Bun',
'lunch' => 'Cashew Nuts and White Mushrooms',
'snack' => 'Dried Mulberries',
'dinner' => 'Eggplant with Chili Sauce');
print "<table>\n";
foreach ($meal as $key => $value) {
print "<tr><td>$key</td><td>$value</td></tr>\n";
}
print '</table>';
Will display:
<table>
<tr><td>breakfast</td><td>Walnut Bun</td></tr>
<tr><td>lunch</td><td>Cashew Nuts and White Mushrooms</td></tr>
<tr><td>snack</td><td>Dried Mulberries</td></tr>
<tr><td>dinner</td><td>Eggplant with Chili Sauce</td></tr>
</table>
- To alternate table row colors:
$row_color = array('red','green');
$color_index = 0;
$meal = array('breakfast' => 'Walnut Bun',
'lunch' => 'Cashew Nuts and White Mushrooms',
'snack' => 'Dried Mulberries',
'dinner' => 'Eggplant with Chili Sauce');
print "<table>\n";
foreach ($meal as $key => $value) {
print '<tr bgcolor="' . $row_color[$color_index] . '">';
print "<td>$key</td><td>$value</td></tr>\n";
// This switches $color_index between 0 and 1
$color_index = 1 - $color_index;
}
print '</table>';
Will display:
<table>
<tr bgcolor="red"><td>breakfast</td><td>Walnut Bun</td></tr>
<tr bgcolor="green"><td>lunch</td><td>Cashew Nuts and White Mushrooms</td></tr>
<tr bgcolor="red"><td>snack</td><td>Dried Mulberries</td></tr>
<tr bgcolor="green"><td>dinner</td><td>Eggplant with Chili Sauce</td></tr>
</table>
- Modifying an array with foreach():
$meals = array('Walnut Bun' => 1,
'Cashew Nuts and White Mushrooms' => 4.95,
'Dried Mulberries' => 3.00,
'Eggplant with Chili Sauce' => 6.50);
foreach ($meals as $dish => $price) {
// $price = $price * 2 does NOT work
$meals[$dish] = $meals[$dish] * 2;
}
// Iterate over the array again and print the changed values
foreach ($meals as $dish => $price) {
printf("The new price of %s is \$%.2f.\n",$dish,$price);
}
- Using foreach() with indexed arrays:
$dinner = array('Sweet Corn and Asparagus',
'Lemon Chicken',
'Braised Bamboo Fungus');
foreach ($dinner as $dish) {
print "You can eat: $dish\n";
}
- Traversing an indexed array with for():
$dinner = array('Sweet Corn and Asparagus',
'Lemon Chicken',
'Braised Bamboo Fungus');
for ($i = 0, $num_dishes = count($dinner); $i < $num_dishes; $i++) {
print "Dish number $i is $dinner[$i]\n";
}
- Alternating table row colors with for():
$row_color = array('red','green');
$dinner = array('Sweet Corn and Asparagus',
'Lemon Chicken',
'Braised Bamboo Fungus');
print "<table>\n";
for ($i = 0, $num_dishes = count($dinner); $i < $num_dishes; $i++) {
print '<tr bgcolor="' . $row_color[$i % 2] . '">';
print "<td>Element $i</td><td>$dinner[$i]</td></tr>\n";
}
print '</table>';
- To ensure access to elements in numeric order of their keys, use for():
for ($i = 0, $num_letters = count($letters); $i < $num_letters; $i++) {
print $letters[$i];
}
To check if an element with a given key exists, use array_key_exists():
meals = array('Walnut Bun' => 1,
'Cashew Nuts and White Mushrooms' => 4.95,
'Dried Mulberries' => 3.00,
'Eggplant with Chili Sauce' => 6.50,
'Shrimp Puffs' => 0); // Shrimp Puffs are free!
$books = array("The Eater's Guide to Chinese Characters",
'How to Cook and Eat in Chinese');
// This is true
if (array_key_exists('Shrimp Puffs',$meals)) {
print "Yes, we have Shrimp Puffs";
}
// This is false
if (array_key_exists('Steak Sandwich',$meals)) {
print "We have a Steak Sandwich";
}
// This is true
if (array_key_exists(1, $books)) {
print "Element 1 is How to Cook in Eat in Chinese";
}
- The array_search() function is similar to in_array(), but if it finds an element it returns its key rather than true. In the example below, array_search() returns the name of the dish that costs 6.50 euros:
$meals = array('Walnut Bun' => 1,
'Cashew Nuts and White Mushrooms' => 4.95,
'Dried Mulberries' => 3.00,
'Eggplant with Chili Sauce' => 6.50,
'Shrimp Puffs' => 0);
$dish = array_search(6.50, $meals);
if ($dish) {
print "$dish costs \$6.50";
}
Modifying arrays
- Interpolation of array elements in strings with double apostrophes:
$meals['breakfast'] = 'Walnut Bun';
$meals['lunch'] = 'Eggplant with Chili Sauce';
$amounts = array(3, 6);
print "For breakfast, I'd like $meals[breakfast] and for lunch, ";
print "I'd like $meals[lunch]. I want $amounts[0] at breakfast and ";
print "$amounts[1] at lunch.";
The unset() function allows you to remove an element from an array:
unset($dishes['Roast Duck']);
Deleting an element with unset() is different from simply assigning it 0 or an empty string. When you use unset(), the element is no longer there when traversing the array or counting the number of its elements. Using unset() on an array representing an inventory is like saying that the store no longer offers a product. Setting the element’s value to 0 or assigning an empty string means that this element is no longer in stock for the moment.
- Creating a string from an array with implode():
$dimsum = array('Chicken Bun','Stuffed Duck Web','Turnip Cake');
$menu = implode(', ', $dimsum);
print $menu;
Will display:
Chicken Bun, Stuffed Duck Web, Turnip Cake
To convert an array without adding a delimiter, use an empty string as the first parameter of implode():
$letters = array('A','B','C','D');
print implode(,$letters);
Will display:
ABCD
- Generating HTML table rows with implode():
$dimsum = array('Chicken Bun','Stuffed Duck Web','Turnip Cake');
print '<tr><td>' . implode('</td><td>',$dimsum) . '</td></tr>';
Will display:
<tr><td>Chicken Bun</td><td>Stuffed Duck Web</td><td>Turnip Cake</td></tr>
As you’ve probably seen, this avoids having to write a loop.
- Converting a string to an array with explode():
$fish = 'Bass, Carp, Pike, Flounder';
$fish_list = explode(', ', $fish);
print "The second fish is $fish_list[1]";
Will display:
The second fish is Carp
Sorting arrays
The sort() function sorts an array by the values of its elements. It should only be used on arrays with numeric keys because it resets these keys during sorting. Here are some arrays before and after a call to sort().
Sorting with sort():
$dinner = array('Sweet Corn and Asparagus',
'Lemon Chicken',
'Braised Bamboo Fungus');
$meal = array('breakfast' => 'Walnut Bun',
'lunch' => 'Cashew Nuts and White Mushrooms',
'snack' => 'Dried Mulberries',
'dinner' => 'Eggplant with Chili Sauce');
print "Before Sorting:\n";
foreach ($dinner as $key => $value) {
print " \$dinner: $key $value\n";
}
foreach ($meal as $key => $value) {
print " \$meal: $key $value\n";
}
sort($dinner);
sort($meal);
print "After Sorting:\n";
foreach ($dinner as $key => $value) {
print " \$dinner: $key $value\n";
}
foreach ($meal as $key => $value) {
print " \$meal: $key $value\n";
}
Will display:
Before Sorting:
$dinner: 0 Sweet Corn and Asparagus
$dinner: 1 Lemon Chicken
$dinner: 2 Braised Bamboo Fungus
$meal: breakfast Walnut Bun
$meal: lunch Cashew Nuts and White Mushrooms
$meal: snack Dried Mulberries
$meal: dinner Eggplant with Chili Sauce
After Sorting:
$dinner: 0 Braised Bamboo Fungus
$dinner: 1 Lemon Chicken
$dinner: 2 Sweet Corn and Asparagus
$meal: 0 Cashew Nuts and White Mushrooms
$meal: 1 Dried Mulberries
$meal: 2 Eggplant with Chili Sauce
$meal: 3 Walnut Bun
- To sort an associative array, use asort(), which preserves the keys and values:
$meal = array('breakfast' => 'Walnut Bun',
'lunch' => 'Cashew Nuts and White Mushrooms',
'snack' => 'Dried Mulberries',
'dinner' => 'Eggplant with Chili Sauce');
print "Before Sorting:\n";
foreach ($meal as $key => $value) {
print " \$meal: $key $value\n";
}
asort($meal);
print "After Sorting:\n";
foreach ($meal as $key => $value) {
print " \$meal: $key $value\n";
}
Will display:
Before Sorting:
$meal: breakfast Walnut Bun
$meal: lunch Cashew Nuts and White Mushrooms
$meal: snack Dried Mulberries
$meal: dinner Eggplant with Chili Sauce
After Sorting:
$meal: lunch Cashew Nuts and White Mushrooms
$meal: snack Dried Mulberries
$meal: dinner Eggplant with Chili Sauce
$meal: breakfast Walnut Bun
- While sort() and asort() sort arrays by the values of their elements, ksort() allows sorting by their keys: the key/value pairs remain identical, but are ordered by keys.
The functions rsort(), arsort() and krsort() are the respective counterparts of sort(), asort() and ksort() for sorting in descending order**. They work exactly the same way, except that the largest key or value (or the last from an alphabetical point of view) will appear first in the sorted array and the following elements will be placed in descending order.**
Using multidimensional arrays
- Creating multidimensional arrays with array():
$meals = array('breakfast' => array('Walnut Bun','Coffee'),
'lunch' => array('Cashew Nuts', 'White Mushrooms'),
'snack' => array('Dried Mulberries','Salted Sesame Crab'));
$lunches = array( array('Chicken','Eggplant','Rice'),
array('Beef','Scallions','Noodles'),
array('Eggplant','Tofu'));
$flavors = array('Japanese' => array('hot' => 'wasabi',
'salty' => 'soy sauce'),
'Chinese' => array('hot' => 'mustard',
'pepper-salty' => 'prickly ash'));
You access the elements of these arrays by using additional pairs of brackets to identify them: each pair goes down one level in the complete array.
Accessing elements of a multidimensional array:
print $meals['lunch'][1]; // White Mushrooms
print $meals['snack'][0]; // Dried Mulberries
print $lunches[0][0]; // Chicken
print $lunches[2][1]; // Tofu
print $flavors['Japanese']['salty'] // soy sauce
print $flavors['Chinese']['hot']; // mustard
- Manipulating multidimensional arrays:
$prices['dinner']['Sweet Corn and Asparagus'] = 12.50;
$prices['lunch']['Cashew Nuts and White Mushrooms'] = 4.95;
$prices['dinner']['Braised Bamboo Fungus'] = 8.95;
$prices['dinner']['total'] = $prices['dinner']['Sweet Corn and Asparagus'] +
$prices['dinner']['Braised Bamboo Fungus'];
$specials[0][0] = 'Chestnut Bun';
$specials[0][1] = 'Walnut Bun';
$specials[0][2] = 'Peanut Bun';
$specials[1][0] = 'Chestnut Salad';
$specials[1][1] = 'Walnut Salad';
// Leaving out the index adds it to the end of the array
// This creates $specials[1][2]
$specials[1][] = 'Peanut Salad';
- Traversing a multidimensional array with foreach():
$flavors = array('Japanese' => array('hot' => 'wasabi',
'salty' => 'soy sauce'),
'Chinese' => array('hot' => 'mustard',
'pepper-salty' => 'prickly ash'));
// $culture is the key and $culture_flavors is the value (an array)
foreach ($flavors as $culture => $culture_flavors) {
// $flavor is the key and $example is the value
foreach ($culture_flavors as $flavor => $example) {
print "A $culture $flavor flavor is $example.\n";
}
}
Will display:
A Japanese hot flavor is wasabi.
A Japanese salty flavor is soy sauce.
A Chinese hot flavor is mustard.
A Chinese pepper-salty flavor is prickly ash.
The first foreach() loop traverses the first dimension of $flavors. The keys stored in $culture are the strings Japanese and Chinese and the values stored in $culture_flavors are the arrays that are the elements of this dimension. The next foreach() traverses these arrays by copying keys like hot and salty into $flavors and values like wasabi and soy sauce into $example. The code block of the second foreach() uses the variables from both foreach() instructions to produce a complete message.
Just as nested foreach() loops traverse a multidimensional associative array, nested for() loops allow traversing a multidimensional array with numeric indices:
$specials = array( array('Chestnut Bun', 'Walnut Bun', 'Peanut Bun'),
array('Chestnut Salad','Walnut Salad', 'Peanut Salad') );
// $num_specials is 2: the number of elements in the first dimension of $specials
for ($i = 0, $num_specials = count($specials); $i < $num_specials; $i++) {
// $num_sub is 3: the number of elements in each sub-array
for ($m = 0, $num_sub = count($specials[$i]); $m < $num_sub; $m++) {
print "Element [$i][$m] is " . $specials[$i][$m] . "\n";
}
}
Will display:
Element [0][0] is Chestnut Bun
Element [0][1] is Walnut Bun
Element [0][2] is Peanut Bun
Element [1][0] is Chestnut Salad
Element [1][1] is Walnut Salad
Element [1][2] is Peanut Salad
To interpolate the value of a multidimensional array in a string between double apostrophes or an in-place document, we must use the syntax to produce the same result as the previous example: in fact, the only difference is the print instruction:
Interpolating a multidimensional array:
$specials = array( array('Chestnut Bun', 'Walnut Bun', 'Peanut Bun'),
array('Chestnut Salad','Walnut Salad', 'Peanut Salad') );
// $num_specials is 2: the number of elements in the first dimension of $specials
for ($i = 0, $num_specials = count($specials); $i < $num_specials; $i++) {
// $num_sub is 3: the number of elements in each sub-array
for ($m = 0, $num_sub = count($specials[$i]); $m < $num_sub; $m++) {
print "Element [$i][$m] is {$specials[$i][$m]}\n";
}
}
Functions
Function declarations and calls
- Declaration of a function called page_header():
function page_header() {
print '<html><head><title>Welcome to my site</title></head>';
print '<body bgcolor="#ffffff">';
}
- Calling a function:
page_header();
print "Welcome, $user";
print "</body></html>";
- Function definitions before or after their call:
function page_header( ) {
print '<html><head><title>Welcome to my site</title></head>';
print '<body bgcolor="#ffffff">';
}
page_header( );
print "Welcome, $user";
page_footer( );
function page_footer( ) {
print '<hr>Thanks for visiting.';
print '</body></html>';
}
I strongly recommend you to code “clean”. Indeed, if you place functions anywhere in your code, it will quickly become messy. You should group functions together and put them at the beginning of your code. I’m not a purist (…well, maybe), but people reviewing your code after you, or even yourself if you take it up a few months later, will appreciate being able to quickly understand the code.
Passing parameters to functions
- Declaration of a function with a parameter (here $color):
function page_header2($color) {
print '<html><head><title>Welcome to my site</title></head>';
print '<body bgcolor="#' . $color . '">';
}
By calling the function like this:
page_header2('cc00cc');
You will get:
<html><head><title>Welcome to my site</title></head><body bgcolor="#cc00cc">
When you define a function that takes a parameter, you must pass a parameter to this function when calling it. Otherwise, the PHP interpreter will produce a warning message to complain about it. If for example, you call page_header2() as follows:
page_header2();
It will display:
PHP Warning: Missing argument 1 for page_header2()
- Using a default value for a parameter:
To avoid this warning, make it so this function can be called without parameters by providing a default value in the function declaration. In this case, if the function is called without parameters, this default value will be taken as the parameter value. To provide a default value, place it after the parameter name. Here this value is cc3399:
function page_header3($color = 'cc3399') {
print '<html><head><title>Welcome to my site</title></head>';
print '<body bgcolor="#' . $color . '">';
}
Default parameter values must be literals, such as 12, cc3399, or a string; they cannot be variables:
$my_color = '#000000';
// This is incorrect: the default value can't be a variable.
function page_header_bad($color = $my_color) {
print '<html><head><title>Welcome to my site</title></head>';
print '<body bgcolor="#' . $color . '">';
}
- Defining a function with 2 parameters:
function page_header4($color, $title) {
print '<html><head><title>Welcome to ' . $title . '</title></head>';
print '<body bgcolor="#' . $color . '">';
}
- Calling a function with 2 parameters:
page_header4('66cc66','my homepage');
- Defining multiple optional parameters:
// One optional argument: it must be last
function page_header5($color, $title, $header = 'Welcome') {
print '<html><head><title>Welcome to ' . $title . '</title></head>';
print '<body bgcolor="#' . $color . '">';
print "<h1>$header</h1>";
}
// Acceptable ways to call this function:
page_header5('66cc99','my wonderful page'); // uses default $header
page_header5('66cc99','my wonderful page','This page is great!');
// no defaults
// Two optional arguments: must be last two arguments
function page_header6($color, $title = 'the page', $header = 'Welcome') {
print '<html><head><title>Welcome to ' . $title . '</title></head>';
print '<body bgcolor="#' . $color . '">';
print "<h1>$header</h1>";
}
// Acceptable ways to call this function:
page_header6('66cc99'); // uses default $title and $header
page_header6('66cc99','my wonderful page'); // uses default $header
page_header6('66cc99','my wonderful page','This page is great!');
// no defaults
// All optional arguments
function page_header6($color = '336699', $title = 'the page', $header = 'Welcome') {
print '<html><head><title>Welcome to ' . $title . '</title></head>';
print '<body bgcolor="#' . $color . '">';
print "<h1>$header</h1>";
}
// Acceptable ways to call this function:
page_header7( ); // uses all defaults
page_header7('66cc99'); // uses default $title and $header
page_header7('66cc99','my wonderful page'); // uses default $header
page_header7('66cc99','my wonderful page','This page is great!');
// no defaults
Return values from functions
Capturing a return value:
$number_to_display = number_format(285266237);
print "The population of the US is about: $number_to_display";
This will display:
The population of the US is about: 285,266,237
To return values from your own functions, use the return keyword, followed by the value to return. The execution of a function stops as soon as the return keyword is encountered and then returns the specified value. The example below defines a function that returns the total amount of a meal after adding VAT and tip. Returning a value from a function:
function restaurant_check($meal, $tax, $tip) {
$tax_amount = $meal * ($tax / 100);
$tip_amount = $meal * ($tip / 100);
$total_amount = $meal + $tax_amount + $tip_amount;
return $total_amount;
}
A return statement can only return one value: syntax like return 15, 23 is not allowed. If you want a function to return multiple values, place them in an array and return it.
Here’s a modified version of the restaurant_check() function that returns a 2-element array, corresponding to the total amount before and after adding the tip.
- Returning an array from a function:
function restaurant_check2($meal, $tax, $tip) {
$tax_amount = $meal * ($tax / 100);
$tip_amount = $meal * ($tip / 100);
$total_notip = $meal + $tax_amount;
$total_tip = $meal + $tax_amount + $tip_amount;
return array($total_notip, $total_tip);
}
- Using an array returned by a function:
$totals = restaurant_check2(15.22, 8.25, 15);
if ($totals[0] < 20) {
print 'The total without tip is less than $20.';
}
if ($totals[1] < 20) {
print 'The total with tip is less than $20.';
}
- Using return values with an if():
if (restaurant_check(15.22, 8.25, 15) < 20) {
print 'Less than $20, I can pay cash.';
} else {
print 'Too expensive, I need my credit card.';
}
- Functions returning true or false:
function can_pay_cash($cash_on_hand, $amount) {
if ($amount > $cash_on_hand) {
return false;
} else {
return true;
}
}
$total = restaurant_check(15.22,8.25,15);
if (can_pay_cash(20, $total)) {
print "I can pay in cash.";
} else {
print "Time for the credit card.";
}
From a function, there are 2 ways to access a global variable. The most direct method is to look them up in a special array called $GLOBALS, because any global variable is accessible as an element of this array. Here’s how to use the $GLOBALS array:
$dinner = 'Curry Cuttlefish';
function macrobiotic_dinner( ) {
$dinner = "Some Vegetables";
print "Dinner is $dinner";
// Succumb to the delights of the ocean
print " but I'd rather have ";
print $GLOBALS['dinner'];
print "\n";
}
macrobiotic_dinner( );
print "Regular dinner is: $dinner";
This will display:
Dinner is Some Vegetables but I'd rather have Curry Cuttlefish
Regular dinner is: Curry Cuttlefish
The 2nd way to access a global variable from a function is to use the global keyword, which tells the PHP interpreter that the subsequent use, in the function, of the indicated variable will refer to this local variable, and not to a local variable: this is called “placing a variable in the local scope”. The global keyword:
$dinner = 'Curry Cuttlefish';
function vegetarian_dinner( ) {
global $dinner;
print "Dinner was $dinner, but now it's ";
$dinner = 'Sauteed Pea Shoots';
print $dinner;
print "\n";
}
print "Regular Dinner is $dinner.\n";
vegetarian_dinner( );
print "Regular dinner is $dinner";
Will display:
Regular Dinner is Curry Cuttlefish.
Dinner was Curry Cuttlefish, but now it's Sauteed Pea Shoots
Regular dinner is Sauteed Pea Shoots
You can also use global with multiple variable names, separated by commas:
global $dinner, $lunch, $breakfast;
Creating HTML forms
Displaying a “Hello”:
if (array_key_exists('my_name',$_POST)) {
print "Hello, " . $_POST['my_name'];
} else {
print<<<_HTML_
<form method="post" action="$_SERVER[PHP_SELF]">
Your name: <input type="text" name="my_name">
<br/>
<input type="submit" value="Say Hello">
</form>
_HTML_;
}
- Form retrieval and display:
- Form submission and result display:
The form is sent back to the same URL as the one that initially requested it because the action attribute of the
Last updated 27 Dec 2010, 21:26 +0200.