Friday, 11 February 2011

Expressions in PHP

Expressions are the most important building stones of PHP. In PHP, almost anything you write is an
expression. The simplest yet most accurate way to define an expression is "anything that has a value".The most basic forms of expressions are constants and variables. When you type "$a = 5", you’re assigning ’5’ into $a. ’5’, obviously, has the value 5, or in other words ’5’ is an expression with the value of 5 (in this case, ’5’ is an integer constant). After this assignment, you’d expect $a’s value to be 5 as well, so if you wrote $b = $a, you’d expect it to behave just as if you wrote $b = 5. In other words, $a is an expression with the value of 5 as well. If everything works right, this is exactly what will happen.
Slightly more complex examples for expressions are functions. For instance, consider the following

   1: function foo () {
   2: return 5;
   3: }


Assuming you’re familiar with the concept of functions (if you’re not, take a look at the chapter about
functions), you’d assume that typing $c = foo() is essentially just like writing$c = 5, and you’re
right. Functions are expressions with the value of their return value. Since foo() returns 5, the value of the expression ’foo()’ is 5. Usually functions don’t just return a static value but compute something.



Of course, values in PHP don’t have to be integers, and very often they aren’t. PHP supports three scalar value types: integer values, floating point values and string values (scalar values are values that you can’t ’break’ into smaller pieces, unlike arrays, for instance). PHP also supports two composite (non-scalar) types: arrays and objects. Each of these value types can be assigned into variables or returned from functions.



So far, users of PHP/FI 2 shouldn’t feel any change. However, PHP takes expressions much further, in the same way many other languages do. PHP is an expression-oriented language, in the sense that almost everything is an expression. Consider the example we’ve already dealt with, ’$a = 5’. It’s easy to see that there are two values involved here, the value of the integer constant ’5’, and the value of $a which is being updated to 5 as well. But the truth is that there’s one additional value involved here, and that’s the value of the assignment itself. The assignment itself evaluates to the assigned value, in this case 5. In practice, it means that ’$a = 5’, regardless of what it does, is an expression with the value 5. Thus, writing something like ’$b = ($a = 5)’ is like writing ’$a = 5; $b = 5;’ (a semicolon marks the end of a statement). Since assignments are parsed in a right to left order, you can also write ’$b = $a = 5’.


Another good example of expression orientation is pre- and post-increment and decrement. Users of
PHP/FI 2 and many other languages may be familiar with the notation of variable++ and variable–.
These are increment and decrement operators. In PHP/FI 2, the statement ’$a++’ has no value (is not an expression), and thus you can’t assign it or use it in any way. PHP enhances the increment/decrement capabilities by making these expressions as well, like in C. In PHP, like in C, there are two types of increment - pre-increment and post-increment. Both pre-increment and post-increment essentially increment the variable, and the effect on the variable is idential. The difference is with the value of the increment expression. Pre-increment, which is written ’++$variable’, evaluates to the incremented value (PHP increments the variable before reading its value, thus the name ’pre-increment’). Post-increment, which is written ’$variable++’ evaluates to the original value of $variable, before it was incremented (PHP increments the variable after reading its value, thus the name ’post-increment’). A very common type of expressions are comparison expressions. These expressions evaluate to either 0 or 1, meaning FALSE or TRUE (respectively). PHP supports > (bigger than), >= (bigger than or equal to), == (equal), < (smaller than) and <= (smaller than or equal to). These expressions are most commonly used inside conditional execution, such as IF statements. The last example of expressions we’ll deal with here is combined operator-assignment expressions. You already know that if you want to increment $a by 1, you can simply write ’$a++’ or ’++$a’. But what if you want to add more than one to it, for instance 3? You could write ’$a++’ multiple times, but this is obviously not a very efficient or comfortable way. A much more common practice is to write ’$a = $a + 3’. ’$a + 3’ evaluates to the value of $a plus 3, and is assigned back into $a, which results in incrementing $a by 3. In PHP, as in several other languages like C, you can write this in a shorter way, which with time would become clearer and quicker to understand as well. Adding 3 to the current value of $a can be written ’$a += 3’. This means exactly "take the value of $a, add 3 to it, and assign it back into $a". In addition to being shorter and clearer, this also results in faster execution. The value of ’$a += 3’, like the value of a regular assignment, is the assigned value. Notice that it is NOT 3, but the combined value of $a plus 3 (this is the value that’s assigned into $a). Any two-place operator can be used in this operator-assignment mode, for example ’$a -= 5’ (subtract 5 from the value of $a), ’$b *= 7’ (multiply the value of $b by 7), etc.



There is one more expression that may seem odd if you haven’t seen it in other languages, the ternary conditional operator:




   1: $first ? $second : $third



If the value of the first subexpression is true (non-zero), then it the second subexpression is evaluated, and that is the result of the conditional expression. Otherwise, the third subexpression is evaluated, and that is the value.


The following example should help you understand pre- and post-increment and expressions in general a bit better:


   1: function double($i) {
   2: return $i*2;
   3: }
   4: $b = $a = 5; /* assign the value five into the variable $a and $b */
   5: $c = $a++; /* post-increment, assign original value of $a
   6: (5) to $c */
   7: $e = $d = ++$b; /* pre-increment, assign the incremented value of
   8: $b (6) to $d and $e */
   9: /* at this point, both $d and $e are equal to 6 */
  10: $f = double($d++); /* assign twice the value of $d before
  11: the increment, 2*6 = 12 to $f */
  12: $g = double(++$e); /* assign twice the value of $e after
  13: the increment, 2*7 = 14 to $g */
  14: $h = $g += 10; /* first, $g is incremented by 10 and ends with the
  15: value of 24. the value of the assignment (24) is
  16: then assigned into $h, and $h ends with the value
  17: of 24 as well. */




In the beginning of the chapter we said that we’ll be describing the various statement types, and as promised, expressions can be statements. However, not every expression is a statement. In this case, a statement has the form of ’expr’ ’;’ that is, an expression followed by a semicolon. In ’$b=$a=5;’, $a=5 is a valid expression, but it’s not a statement by itself. ’$b=$a=5;’ however is a valid statement.


One last thing worth mentioning is the truth value of expressions. In many events, mainly in conditional execution and loops, you’re not interested in the specific value of the expression, but only care about whether it means TRUE or FALSE (PHP doesn’t have a dedicated boolean type). The truth value of expressions in PHP is calculated in a similar way to perl. Any numeric non-zero numeric value is TRUE, zero is FALSE. Be sure to note that negative values are non-zero and are thus considered TRUE! The empty string and the string "0" are FALSE; all other strings are TRUE. With non-scalar values (arrays and objects) - if the value contains no elements it’s considered FALSE, otherwise it’s considered TRUE.


PHP provides a full and powerful implementation of expressions, and documenting it entirely goes beyond the scope of this manual. The above examples should give you a good idea about what expressions are and how you can construct useful expressions. Throughout the rest of this manual we’ll write expr to indicate any valid PHP expression.

GET and POST in PHP

HTML Forms (GET and POST)
When a form is submitted to a PHP script, any variables from that form will be automatically made
available to the script by PHP. For instance, consider the following form:
Example : Simple form variable

   1: <form action="foo.php3" method="post">
   2: Name: <input type="text" name="name"><br>
   3: <input type="submit">
   4: </form>


When submitted, PHP will create the variable $name, which will will contain whatever what entered into the Name: field on the form. PHP also understands arrays in the context of form variables, but only in one dimension. You may, for example, group related variables together, or use this feature to retrieve values from a multiple select input:
Example : More complex form variables


   1: <form action="array.html" method="post">
   2: Name: <input type="text" name="personal[name]"><br>
   3: Email: <input type="text" name="personal[email]"><br>
   4: Beer: <br>
   5: <select multiple name="beer[]">
   6: <option value="warthog">Warthog
   7: <option value="guinness">Guinness
   8: </select>
   9: <input type="submit">
  10: </form>

If PHP’s track_vars feature is turned on, either by the track_vars configuration setting or the
<?php_track_vars?> directive, then variables submitted via the POST or GET methods will also be
found in the global associative arrays $HTTP_POST_VARS and $HTTP_GET_VARS as appropriate.

Variable scope in PHP

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. 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:

   1: $a = 1; /* global scope */
   2: Function Test () {
   3: echo $a; /* reference to local scope variable */
   4: }
   5: 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:


   1: $a = 1;
   2: $b = 2;
   3: Function Sum () {
   4: global $a, $b;
   5: $b = $a + $b;
   6: }
   7: Sum ();
   8: 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:


   1: $a = 1;
   2: $b = 2;
   3: Function Sum () {
   4: $GLOBALS["b"] = $GLOBALS["a"] + $GLOBALS["b"];
   5: }
   6: Sum ();
   7: 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:


   1: Function Test () {
   2: $a = 0;
   3: echo $a;
   4: $a++;
   5: }

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:


   1: Function Test () {
   2: static $a = 0;
   3: echo $a;
   4: $a++;
   5: }

Now, every time the Test() function is called it will print the value of $a and increment it.
Static variables are also essential when functions are called recursively. 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:


   1: Function Test () {
   2: static $count = 0;
   3: $count++;
   4: echo $count;
   5: if ($count < 10) {
   6: Test ();
   7: }
   8: $count-;
   9: }

Type casting in PHP

Type casting in PHP works much as it does in C: the name of the desired type is written in parentheses before the variable which is to be cast.

   1: $foo = 10;                 // $foo is an integer
   2: $bar = (double) $foo;      // $bar is a double



The casts allowed are:
• (int), (integer) - cast to integer
• (real), (double), (float) - cast to double
• (string) - cast to string
• (array) - cast to array
• (object) - cast to object


Note that tabs and spaces are allowed inside the parentheses, so the following are functionally
equivalent:




   1: $foo = (int) $bar;
   2: $foo = ( int ) $bar;

Type juggling in PHP

PHP does not require (or support) explicit type definition in variable declaration; a variable’s type is
determined by the context in which that variable is used. That is to say, if you assign a string value to
variable var, var becomes a string. If you then assign an integer value to var, it becomes an integer.
An example of PHP’s automatic type conversion is the addition operator ’+’. If any of the operands is a double, then all operands are evaluated as doubles, and the result will be a double. Otherwise, the
operands will be interpreted as integers, and the result will also be an integer. Note that this does NOT change the types of the operands themselves; the only change is in how the operands are evaluated.
$foo = "0";                                    // $foo is string (ASCII 48)
$foo++;                                        // $foo is the string "1" (ASCII 49)
$foo += 1;                                    // $foo is now an integer (2)

$foo = $foo + 1.3;                        // $foo is now a double (3.3)
$foo = 5 + "10 Little Piggies";      // $foo is integer (15)
$foo = 5 + "10 Small Pigs";         // $foo is integer (15)
If the last two examples above seem odd, see String conversion.
If you wish to force a variable to be evaluated as a certain type, see the section on Type casting. If you wish to change the type of a variable, see settype.

Objects in PHP

Object Initialization
To initialize an object, you use the new statement to instantiate the object to a variable.

   1: class foo {
   2: function do_foo () {
   3: echo "Doing foo.";
   4: }
   5: }
   6: $bar = new foo;
   7: $bar -> do_foo ();

PHP Arrays

Arrays actually act like both hash tables (associative arrays) and indexed arrays (vectors).

Single Dimension Arrays
PHP supports both scalar and associative arrays. In fact, there is no difference between the two. You can
create an array using the list or array functions, or you can explicitly set each array element value.

$a[0] = "abc";
$a[1] = "def";
$b["foo"] = 13;

You can also create an array by simply adding values to the array.

$a[] = "hello"; // $a[2] == "hello"
$a[] = "world"; // $a[3] == "world"

Arrays may be sorted using the asort, arsort, ksort, rsort, sort, uasort, usort, and uksort
functions depending on the type of sort you want.


You can count the number of items in an array using the count function.
You can traverse an array using next and prev functions. Another common way to traverse an array is to use the each function.


Multi-Dimensional Arrays
Multi-dimensional arrays are actually pretty simple. For each dimension of the array, you add another
[key] value to the end:
$a[1] = $f; # one dimensional examples
$a["foo"] = $f;
$a[1][0] = $f; # two dimensional

$a["foo"][2] = $f; # (you can mix numeric and associative
indices)
$a[3]["bar"] = $f; # (you can mix numeric and associative
indices)
$a["foo"][4]["bar"][0] = $f; # four dimensional!
You can "fill up" multi-dimensional arrays in many ways, but the trickiest one to understand is how to
use the array command for associative arrays. These two snippets of code fill up the one-dimensional array in the same way:
# Example 1:

   1: $a["color"] = "red";
   2: $a["taste"] = "sweet";
   3: $a["shape"] = "round";
   4: $a["name"] = "apple";
   5: $a[3] = 4;

# Example 2:


   1: $a = array(
   2: "color" => "red",
   3: "taste" => "sweet",
   4: "shape" => "round",
   5: "name" => "apple",
   6: 3 => 4
   7: );

The array function can be nested for multi-dimensional arrays:


   1: <?
   2: $a = array(
   3: "apple" => array(
   4: "color" => "red",
   5: "taste" => "sweet",
   6: "shape" => "round"
   7: ),
   8: "orange" => array(
   9: "color" => "orange",
  10: "taste" => "sweet",
  11: "shape" => "round"
  12: ),
  13: "banana" => array(
  14:  
  15: "color" => "yellow",
  16: "taste" => "paste-y",
  17: "shape" => "banana-shaped"
  18: )
  19: );
  20: echo $a["apple"]["taste"]; # will output "sweet"
  21: ?>

Data types in PHP

PHP supports the following types:


• integer
• floating-point numbers
• string
• array
• object


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.
If you would like to force a variable to be converted to a certain type, you may either cast the variable or
use the settype function on it.
Note that a variable may behave in different manners in certain situations, depending on what type it is a
the time. For more information, see the section on Type Juggling.
Integers
Integers can be specified using any of the following syntaxes:


$a = 1234; # decimal number
$a = -123; # a negative number
$a = 0123; # octal number (equivalent to 83 decimal)
$a = 0x12; # hexadecimal number (equivalent to 18 decimal)


Floating point numbers
Floating point numbers ("doubles") can be specified using any of the following syntaxes:

$a = 1.234;
$a = 1.2e3;

Strings
Strings can be specified using one of two sets of delimiters.

If the string is enclosed in double-quotes ("), variables within the string will be expanded (subject to
some parsing limitations). As in C and Perl, the backslash ("\") character can be used in specifying
special characters:
Table 5-1. Escaped characters




sequence meaning
\n newline
\r carriage
\t horizontal tab
\\ backslash
\$ dollar sign
\" double-quote


You can escape any other character, but a warning will be issued at the highest warning level.
The second way to delimit a string uses the single-quote ("’") character, which does not do any variable expansion or backslash processing (except for "\\" and "\’" so you can insert backslashes and single-quotes in a singly-quoted string).
String conversion
When a string is evaluated as a numeric value, the resulting value and type are determined as follows.
The string will evaluate as a double if it contains any of the characters ’.’, ’e’, or ’E’. Otherwise, it will
evaluate as an integer.
The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an ’e’ or ’E’ followed by one or more digits.
When the first expression is a string, the type of the variable will depend on the second expression.

$foo = 1 + "10.5"; // $foo is double (11.5)
$foo = 1 + "-1.3e3"; // $foo is double (-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 double (11)

 


For more information on this conversion, see the Unix manual page for strtod(3).