Skip to content

3. The Basics of PHP

3.1. A first example

Below is a program demonstrating the basic features of PHP.

3.1.1. The program (example_01)


<?php

// this is a comment
// variable used without being declared
$name = "dupont";

// a screen display
print "name=$name\n";

// an array with elements of different types
$array = array("one", "two", 3, 4);

// its number of elements
$n = count($array);

// a loop
for ($i = 0; $i < $n; $i++)
  print "array[$i] = $array[$i]\n";

// initializing 2 variables with the contents of an array
list($string1, $string2) = array("string1", "string2");

// concatenation of the 2 strings
$string3 = $string1 . $string2;

// display result
print "[$string1,$string2,$string3]\n";

// using the function
display($string1);

// the type of a variable can be determined
displayType($n);
displayType($string1);
displayType($array);

// The type of a variable can change during execution
$n = "has changed";
displayType($n);

// a function can return a result
$res1 = f1(4);
print "res1=$res1\n";

// a function can return an array of values
list($res1, $res2, $res3) = f2();
print "(res1,res2,res3)=[$res1,$res2,$res3]\n";

// we could have retrieved these values into an array
$t = f2();
for ($i = 0; $i < count($t); $i++)
  print "t[$i]=$t[$i]\n";

// tests
for ($i = 0; $i < count($t); $i++)
// displays only strings
  if (getType($t[$i]) == "string")
    print "t[$i]=$t[$i]\n";

// other tests
for ($i = 0; $i < count($t); $i++){
// displays only integers greater than 10
  if (getType($t[$i]) == "integer" and $t[$i] > 10)
    print "t[$i]=$t[$i]\n";
}

// a while loop
$t = array(8, 5, 0, -2, 3, 4);
$i = 0;
$sum = 0;
while ($i < count($t) and $t[$i] > 0) {
  print "t[$i]=$t[$i]\n";
  $sum+=$t[$i];   //$sum=$sum+$t[$i]
  $i++;             //$i=$i+1
}
print "sum=$sum\n";

// end of program
exit;

//----------------------------------
function display($string) {
  // display $string
  print "string=$string\n";
}

//----------------------------------
function displayType($variable) {
  // displays the type of $variable
  print "type[$variable]=" . getType($variable) . "\n";
}

//----------------------------------
function f1($param) {
  // adds 10 to $param
  return $param + 10;
}

//----------------------------------
function f2() {
  // returns 3 values
  return array("one", 0, 100);
}
?>

The results:

name=dupont
array[0]=one
array[1]=two
array[2]=3
array[3]=4
[string1, string2, string1string2]
string = string1
type[4] = integer
type[string1] = string
type[Array] = array
type[changed]=string
res1=14
(res1, res2, res3) = [1, 0, 100]
t[0] = one
t[1] = 0
t[2] = 100
t[0] = 1
t[2] = 100
t[0]=8
t[1]=5
sum=13

Comments

  • Line 5: In PHP, variable types are not declared. Variables have a dynamic type that can change over time
  • $name represents the variable with the identifier name
  • Line 8: To display text on the screen, you can use the print statement or the echo statement
  • Line 11: The keyword *array* is used to define an array. The variable $name[$i] represents the $ith element of the $array array.
  • line 14: the count($tableau) function returns the number of elements in the $tableau array
  • line 18: strings are enclosed in double quotes " or single quotes '. Inside double quotes, variables $variable are evaluated, but not inside single quotes.
  • line 21: the list function allows you to group variables into a list and assign a value to them with a single assignment operation. Here, $string1="string1" and $string2="string2".
  • line 24: the . operator is the string concatenation operator.
  • line 88: the keyword function defines a function. A function may or may not return values using the return statement. The calling code can ignore or retrieve the results of a function. A function can be defined anywhere in the code.
  • Line 90: The predefined function getType($variable) returns a string representing the type of $variable. This type may change over time.
  • Line 79: The predefined function exit terminates the script.

3.2. Variable scope

3.2.1. Program 1 (example_02)


<?php

// scope of variables

function f1() {
  // we use the global variable $i
  $i = &$GLOBALS["i"];
  $i++;
  $j = 10;
  print "f1[i,j]=[$i,$j]\n";
}

function f2() {
  // we use the global variable $i
  $i = &$GLOBALS["i"];
  $i++;
  $j = 20;
  print "f2[i,j]=[$i,$j]\n";
}

function f3() {
  // we use a local variable $i
  $i = 4;
  $j = 30;
  print "f3[i,j]=[$i,$j]\n";
}

// tests
$i = 0;
$j = 0;  // these two variables are known to a function f via the $GLOBALS array
f1();
f2();
f3();
print "test[i,j]=[$i,$j]\n";
?>

The results:

1
2
3
4
f1[i,j]=[1,10]
f2[i,j]=[2,20]
f3[i,j]=[4,30]
test[i,j] = [2,0]

Comments

  • Lines 29–30: define two variables, $i and $j, in the main program. These variables are not known within the functions. Thus, in line 9, the variable $j in function f1 is a local variable of function f1 and is different from the variable $j in the main program. A function can access a variable $variable from the main program via an array of global variables called $GLOBALS. In line 7, the notation $GLOBALS["i"] refers to the global variable $i of the main program. If we write
$i=$GLOBALS["i"]

a local variable $i is assigned the value of the global variable $i. These are two different variables, and modifying the local variable $i will not modify the global variable $i. The notation

$i=&Globals["i"]

causes the local variable $i to have the same memory address as the global variable $i. Manipulating the local variable $i is then equivalent to manipulating the global variable $i.

3.2.2. Program 2 (example_03)


<?php

// A variable's scope is global to code blocks
$i = 0; {
  $i = 4;
  $i++;
}
print "i=$i\n";
?>

The results:

i=5

Comments

In some languages, a variable defined within curly braces has a scope limited to those braces: it is not accessible outside of them. The results above show that this is not the case in PHP. The variable $i defined on line 5 inside the curly braces is the same as the one used on lines 4 and 8 outside of them.

3.3. Arrays

3.3.1. Classic one-dimensional arrays (example_04)


<?php

// classic arrays
// initialization
$tab1 = array(0, 1, 2, 3, 4, 5);

// loop - 1
print "tab1 has " . count($tab1) . " elements\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// loop - 2
print "tab1 has " . count($tab1) . " elements\n";
reset($tab1);
while (list($key, $value) = each($tab1))
  print "tab1[$key]=$value\n";

// adding elements
$tab1[] = $i++;
$tab1[] = $i++;

// loop - 3
print "tab1 has " . count($tab1) . " elements\n";
$i = 0;
foreach ($tab1 as $element) {
  print "tab1[$i]=$element\n";
  $i++;
}

// remove last element
array_pop($tab1);

// loop - 4
print "tab1 has " . count($tab1) . " elements\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// remove first element
array_shift($tab1);

// loop - 5
print "tab1 has " . count($tab1) . " elements\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i] = $tab1[$i]\n";

// Add to the end of the array
array_push($tab1, -2);

// loop - 6
print "tab1 has " . count($tab1) . " elements\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// Add to the beginning of the array
array_unshift($tab1, -1);

// loop - 7
print "tab1 has " . count($tab1) . " elements\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";
?>

The results:

tab1 has 6 elements
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4] = 4
tab1[5]=5
tab1 has 6 elements
tab1[0] = 0
tab1[1] = 1
tab1[2]=2
tab1[3]=3
tab1[4] = 4
tab1[5]=5
tab1 has 8 elements
tab1[0] = 0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4] = 4
tab1[5]=5
tab1[6]=6
tab1[7]=7
tab1 has 7 elements
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4] = 4
tab1[5]=5
tab1[6]=6
tab1 has 6 elements
tab1[0]=1
tab1[1]=2
tab1[2]=3
tab1[3]=4
tab1[4] = 5
tab1[5]=6
tab1 has 7 elements
tab1[0]=1
tab1[1]=2
tab1[2]=3
tab1[3]=4
tab1[4] = 5
tab1[5]=6
tab1[6]=-2
tab1 has 8 elements
tab1[0]=-1
tab1[1]=1
tab1[2]=2
tab1[3] = 3
tab1[4] = 4
tab1[5]=5
tab1[6]=6
tab1[7]=-2

Comments

The program above demonstrates operations for manipulating an array of values. There are two notations for arrays in PHP:

$array = array("one", 2, "three")
$opposites = array("small" => "large", "beautiful" => "ugly", "expensive" => "cheap")

Array 1 is called an array, and array 2 is called a dictionary, where elements are denoted as key => value. The notation $opposites["beautiful"] refers to the value associated with the key "beautiful." Here, that value is the string "ugly." Array 1 is simply a variant of the dictionary and could be written as:

$array=array(0=>"one",1=>2,2=>"three")

Thus, we have $array[2]="three". Ultimately, there are only dictionaries. In the case of a classic array of n elements, the keys are the integers in the range [0,n-1].

  • Line 15: The each($array) function allows you to iterate over a dictionary. On each call, it returns a (key, value) pair from it.
  • Line 14: The reset($dictionary) function sets the each function to the first (key, value) pair in the dictionary.
  • line 15: the while loop stops when the each function returns an empty pair at the end of the dictionary.
  • line 19: the notation $array[]=value adds the element value as the last element of $array.
  • line 25: the array is iterated over using a foreach. This syntax allows you to iterate over a dictionary, and therefore an array, using two syntaxes:
foreach($dictionary as $key=>$value)
foreach($array as $value)

The first syntax returns a (key,value) pair on each iteration, while the second syntax returns only the value element of the dictionary.

  • Line 31: The array_pop($array) function removes the last element from $array
  • line 39: the array_shift($array) function removes the first element from $array
  • line 47: the array_push($array,value) function adds value as the last element of $array
  • line 39: the array_unshift($array,value) function adds value as the first element of $array

3.3.2. The dictionary (example_05)


<?php

// dictionaries
$couples = array("Pierre" => "Gisèle", "Paul" => "Virginie", "Jacques" => "Lucette", "Jean" => "");

// loop - 1
print "Number of elements in the dictionary: " . count($couples) . "\n";
reset($couples);
while (list($key, $value) = each($couples))
  print "spouses[$key]=$value\n";

// Sort the dictionary by key
ksort($pairs);

// loop - 2
reset($pairs);
while (list($key, $value) = each($pairs))
  print "pairs[$key]=$value\n";

// list of dictionary keys
$keys = array_keys($pairs);
for ($i = 0; $i < count($keys); $i++)
  print "keys[$i] = $keys[$i]\n";

// list of dictionary values
$values = array_values($pairs);
for ($i = 0; $i < count($values); $i++)
  print "values[$i]=$values[$i]\n";

// search for a key
exists($pairs, "Jacques");
exists($pairs, "Lucette");
exists($couples, "Jean");

// delete a key-value pair
unset($spouses["Jean"]);
print "Number of elements in the dictionary: " . count($spouses) . "\n";
foreach ($couples as $key => $value) {
  print "spouses[$key]=$value\n";
}

// end
exit;

function exists($couples, $husband) {
  // checks if the key $husband exists in the $spouses dictionary
  if (isset($spouses[$husband]))
    print "The key [$mari] exists with the value [$conjoints[$mari]]\n";
  else
    print "The key [$husband] does not exist\n";
}

?>

The results:

Number of elements in the dictionary: 4
spouses[Pierre]=Gisèle
spouses[Paul]=Virginie
spouses[Jacques]=Lucette
spouses[Jean]=
spouses[Jacques]=Lucette
spouses[Jean]=
spouses[Paul]=Virginie
spouses[Pierre]=Gisèle
keys[0]=Jacques
keys[1]=Jean
keys[2]=Paul
keys[3]=Pierre
values[0]=Lucette
values[1]=
values[2]=Virginie
values[3]=Gisèle
The key [Jacques] exists and is associated with the value [Lucette]
The key [Lucette] does not exist
The key [Jean] exists associated with the value []
Number of elements in the dictionary: 3
spouses[Jacques]=Lucette
spouses[Paul]=Virginie
spouses[Pierre]=Gisèle

Comments

The code above applies to a dictionary what we previously saw for a simple array. We will only comment on the new features:

  • line 13: the ksort (key sort) function sorts a dictionary in the natural order of the keys.
  • line 21: the array_keys($dictionary) function returns the list of the dictionary’s keys as an array
  • line 26: the array_values($dictionary) function returns the list of the dictionary’s values as an array
  • line 47: the isset($variable) function returns true if the $variable has been defined, false otherwise.
  • Line 36: The unset($variable) function deletes the $variable.

3.3.3. Multidimensional arrays (example_06)


<?php

// Classic multidimensional arrays
// initialization
$multi = array(array(0, 1, 2), array(10, 11, 12, 13), array(20, 21, 22, 23, 24));
// iteration
for ($i1 = 0; $i1 < count($multi); $i1++)
  for ($i2 = 0; $i2 < count($multi[$i1]); $i2++)
    print "multi[$i1][$i2]=" . $multi[$i1][$i2] . "\n";
// multidimensional arrays
// initialization
$multi = array("zero" => array(0, 1, 2), "one" => array(10, 11, 12, 13), "two" => array(20, 21, 22, 23, 24));
// iteration
foreach ($multi as $key => $value)
  for ($i2 = 0; $i2 < count($value); $i2++)
    print "multi[$key][$i2]=" . $multi[$key][$i2] . "\n";
?>

Results:

multi[0][0]=0
multi[0][1]=1
multi[0][2]=2
multi[1][0]=10
multi[1][1]=11
multi[1][2]=12
multi[1][3]=13
multi[2][0]=20
multi[2][1]=21
multi[2][2]=22
multi[2][3]=23
multi[2][4]=24
multi[zero][0]=0
multi[zero][1]=1
multi[zero][2]=2
multi[one][0]=10
multi[one][1]=11
multi[one][2]=12
multi[one][3]=13
multi[two][0]=20
multi[two][1]=21
multi[two][2]=22
multi[two][3]=23
multi[two][4]=24

Comments

  • line 5: the elements of the $multi array are themselves arrays
  • line 12: the $multi array becomes a dictionary (key, value) where each value is an array


<?php

// string to array
$string = "1:2:3:4";
$array = explode(":", $string);

// iterate through array
print "array has " . count($tab) . " elements\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n";

// array to string
$string2 = implode(":", $tab);
print "string2=$string2\n";

// let's add an empty field
$string.=":";
print "string=$string\n";
$tab = explode(":", $string);

// loop through the array
print "tab has " . count($tab) . " elements\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n"; // we now have 5 elements, the last one being empty
  
// let's add an empty field again
$string.=":";
print "string=$string\n";
$tab = explode(":", $string);

// iterate through the array
print "tab a " . count($tab) . " elements\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n"; // we now have 6 elements, the last two being empty
?>

Results:

tab has 4 elements
tab[0]=1
tab[1]=2
tab[2]=3
tab[3]=4
string2 = 1:2:3:4
array=1:2:3:4:
tab with 5 elements
tab[0]=1
tab[1]=2
tab[2]=3
tab[3]=4
tab[4]=
string = 1:2:3:4::
tab has 6 elements
tab[0]=1
tab[1]=2
tab[2]=3
tab[3]=4
tab[4]=
tab[5]=

Comments

  • Line 5: The explode($separator,$string) function retrieves the fields of $string separated by $separator. Thus, explode(":",$string) returns the elements of $string separated by the string ":" as an array.
  • The implode($separator,$array) function performs the opposite operation of the explode function. It returns a string consisting of the elements of $array separated by $separator.

3.4. Strings

3.4.1. Syntax (example_08)


<?php

// string notation
$string1 = "one";
$string2 = 'one';
print "[$string1,$string2]\n";
?>

Results:

[one,one]

3.4.2. Comparison (example_09)


<?php

// string comparison tests
compare("abcd", "abcd");
compare("", "");
compare("1", "");
exit;

function compare($string1, $string2) {
  // compare string1 and string2
  if ($string1 == $string2)
    print "[$string1] is equal to [$string2]\n";
  else
    print "[$string1] is different from [$string2]\n";
}

?>

Results:

1
2
3
[abcd] is equal to [abcd]
[] is equal to []
[1] is not equal to []

3.5. Regular expressions (example_10)


<?php

// Regular expressions in PHP
// extract the different fields from a string

// the pattern: a sequence of digits surrounded by any characters
// we only want to extract the sequence of digits
$pattern = "/(\d+)/";
// compare the string to the pattern
compare($pattern, "xyz1234abcd");
compare($pattern, "12 34");
compare($pattern, "abcd");

// the pattern: a sequence of digits surrounded by any characters
// We want the sequence of digits as well as the fields that follow and precede it
$pattern = "/^(.*?)(\d+)(.*?)$/";
// we match the string against the pattern
compare($pattern, "xyz1234abcd");
compare($pattern, "12 34");
compare($pattern, "abcd");

// the pattern - a date in dd/mm/yy format
$pattern = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";
compare($template, "10/05/97");
compare($template, "  04/04/01  ");
compare($pattern, "5/1/01");

// the pattern - a decimal number
$pattern = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";
compare($pattern, "187.8");
compare($pattern, "-0.6");
compare($pattern, "4");
compare($pattern, ".6");
compare($pattern, "4.");
compare($model, " + 4");

// end
exit;

// --------------------------------------------------------------------------
function compare($pattern, $string) {
  // compares the string $string to the pattern $pattern
  // compares the string to the pattern
  $match = preg_match($pattern, $string, $fields);
  // display results
  print "\nResults($pattern,$string)\n";
  if ($match) {
    for ($i = 0; $i < count($fields); $i++)
      print "fields[$i] = $fields[$i]\n";
  } else
    print "The string [$string] does not match the pattern [$pattern]\n";
}
?>

Results:

Results(/(\d+)/,xyz1234abcd)
fields[0]=1234
fields[1]=1234

Results(/(\d+)/,12 34)
fields[0]=12
fields[1]=12

Results(/(\d+)/,abcd)
The string [abcd] does not match the pattern [/(\d+)/]

Results(/^(.*?)(\d+)(.*?)$/,xyz1234abcd)
fields[0]=xyz1234abcd
fields[1]=xyz
fields[2]=1234
fields[3]=abcd

Results(/^(.*?)(\d+)(.*?)$/,12 34)
fields[0]=12 34
fields[1]=
fields[2]=12
fields[3] = 34

Results(/^(.*?)(\d+)(.*?)$/,abcd)
The string [abcd] does not match the pattern [/^(.*?)(\d+)(.*?)$/]

Results(/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/,10/05/97)
fields[0]=10/05/97
fields[1]=10
fields[2]=05
fields[3]=97

Results(/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/,  04/04/01  )
fields[0]=  04/04/01  
fields[1]=04
fields[2]=04
fields[3]=01

Results(/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/,5/1/01)
The string [5/1/01] does not match the pattern [/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/]

Results(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,187.8)
fields[0]=187.8
fields[1]=
fields[2]=187.8

Results(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,-0.6)
fields[0]=-0.6
fields[1]=-
fields[2]=0.6

Results(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,4)
fields[0]=4
fields[1]=
fields[2]=4

Results(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,.6)
fields[0]=.6
fields[1]=
fields[2]=.6

Results(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,4.)
fields[0]=4.
fields[1]=
fields[2]=4.

Results(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/, + 4)
fields[0] = + 4
fields[1]=+
fields[2]=4

Comments

  • Lines 3-4: Here we use regular expressions to extract the various fields from a string. Regular expressions allow us to overcome the limitations of the implode function. The principle is to compare a string to another string called a pattern using the preg_match function:

$matches = preg_match($pattern, $string, $fields);

The preg_match function returns a boolean value indicating whether the pattern can be found in the string. If so, $fields[0] represents the substring matching the pattern. Furthermore, if the pattern contains subpatterns enclosed in parentheses, $champs[1] is the portion of $string corresponding to the first subpattern, $champs[2] is the portion of $string corresponding to the second subpattern, and so on...

Consider the first example. The pattern is defined on line 8: it denotes a sequence of one or more (+) digits (\d) located anywhere in a string. Furthermore, the pattern defines a subpattern enclosed in parentheses.

  • Line 10: the pattern /(\d+)/ (a sequence of one or more digits anywhere in the string) is compared to the string "xyz1234abcd". We see that the substring 1234 matches the pattern. Therefore, $fields[0] will be equal to "1234". Furthermore, the pattern has subpatterns enclosed in parentheses. We will have $champs[1]="1234".
  • Line 11: The pattern /(\d+)/ is compared to the string "12 34". We see that the substrings 12 and 34 match the pattern. The comparison stops at the first substring that matches the pattern. Therefore, $champs[0] = 12 and $champs[1] = 12.
  • Line 12: The pattern /(\d+)/ is compared to the string "abcd". No match is found.

Let’s explain the patterns used in the rest of the code:


$pattern = "/^(.*?)(\d+)(.*?)$/";

start of string (^), then 0 or more (*) arbitrary characters (.), then 1 or more (+) digits, then again 0 or more (*) arbitrary characters (.). The pattern (.*) denotes 0 or more arbitrary characters. Such a pattern will match any string. Thus, the pattern /^(.*)(\d+)(.*)$/ will never be found because the first subpattern (.*) will consume the entire string. The pattern (.*?)(\d+) denotes 0 or more arbitrary characters up to the next subpattern (?), in this case \d+. Therefore, the digits are no longer captured by the pattern (.*). The pattern above thus matches [start of string (^), a sequence of any characters (.*?), a sequence of one or more digits (\d+), a sequence of any characters (.*?), end of string ($)].


$pattern = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";

matches [start of string (^), 2 digits (\d\d), the character / (\/), 2 digits, /, 2 digits, a sequence of 0 or more spaces (\s*), end of string ($)]


$pattern = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";

[start of string (^), 0 or more spaces (\s*), a + or - sign [+|-] occurring 0 or 1 time (?), a sequence of 0 or more spaces (\s*), 1 or more digits followed by a decimal point followed by zero or more digits (\d+\.\d*) or (|) a decimal point (\.) followed by one or more digits (\d+) or (|) one or more digits (\d+), a sequence of 0 or more spaces (\s*)].

3.6. Function parameter passing mode (example_11)


<?php

// parameter passing mode

function f(&$i, $j) {
  // $i will be passed by reference
  // $j will be passed by value
  $i++;
  $j++;
  print "f[i,j]=[$i,$j]\n";
}

// ----------------------------------------tests
$i = 0;
$j = 0;
// $i and $j passed by value
f($i, $j);
print "test[i,j]=[$i,$j]\n";
?>

Results:

f[i,j]=[1,1]
test[i,j]=[1,0]

Comments

The code above demonstrates the two ways of passing parameters to a function. Let’s consider the following example:

1
2
3
4
5
6
7
function f(&$a,$b){

}

// main program
$i=10; $j=20;
f($i, $j);
  • line 1: defines the formal parameters $a and $b of function f. This function manipulates these two formal parameters and returns a result.
  • line 7: calls the function f with two actual parameters $i and $j. The bindings between the formal parameters ($a, $b) and the actual parameters ($i, $j) are defined by line 7
  • &$a: the & symbol indicates that the formal parameter $a will take on the value of the address of the actual parameter $i. In other words, $a and $i are two references to the same memory location. Manipulating the formal parameter $a is equivalent to manipulating the actual parameter $i. This is demonstrated by the code execution. This passing method is suitable for output parameters and large data sets such as arrays and dictionaries. This passing method is called pass-by-reference.
  • $b: The formal parameter $b will take on the value of the actual parameter $j. This is passing by value. The formal and actual parameters are two different variables. Manipulating the formal parameter $b has no effect on the actual parameter $j. This is demonstrated by the code execution. This passing mode is suitable for input parameters.
  • Consider the swap function, which takes two formal parameters $a and $b. The function swaps the values of these two parameters. Thus, during a call to swap($i,$j), the calling code expects the values of the two actual parameters to be swapped. These are therefore output parameters (they are modified). We will therefore write:
function swap(&$a,&$b){....}

3.7. Results returned by a function (example_12)


<?php

// results returned by a function
// a function can return multiple values in an array
list($res1, $res2, $res3) = f1(10);
print "[$res1,$res2,$res3]\n";
$res = f1(10);
for ($i = 0; $i < count($res); $i++)
  print "res[$i]=$res[$i]\n";

// a function can return a pseudo-object
$res = f2(10);
print "[$res->res1,$res->res2,$res->res3]\n";

// end
exit;

// function f1
function f1($value) {
  // returns an array ($value+1, $value+2, $value+3)
  return array($value + 1, $value + 2, $value + 3);
}

// function f2
function f2($value) {
  // returns a pseudo-object ($value+1, $value+2, $value+3)
  $res->res1 = $value + 1;
  ;
  $res->res2 = $value + 2;
  $res->res3 = $value + 3;
  // returns the object
  return $res;
}

?>

Results

1
2
3
4
5
[11,12,13]
res[0]=11
res[1]=12
res[2]=13
[11,12,13]

Comments

  • The previous program shows that a PHP function can return a set of results rather than a single one, in the form of an array or an object. The concept of an object is explained in more detail below
  • lines 19–22: the function f1 returns multiple values in the form of an array
  • lines 25–33: the function f2 returns multiple values in the form of an object

3.8. Text files (example_13)


<?php

// sequential processing of a text file
// This is a set of lines in the format login:pwd:uid:gid:infos:dir:shell
// Each line is stored in a dictionary in the form login => uid:gid:infos:dir:shell

// We set the file name
$INFOS = "infos.txt";

// open it for writing
if (!$fic = fopen($INFOS, "w")) {
  print "Error opening file $INFOS for writing\n";
  exit;
}

// generate arbitrary content
for ($i = 0; $i < 100; $i++)
  fputs($fic, "login$i:pwd$i:uid$i:gid$i:infos$i:dir$i:shell$i\n");
// close the file
fclose($fic);

// process it - fgets preserves the end-of-line character
// this prevents an empty string from being retrieved when reading a blank line
// open it for writing
if (!$fic = fopen($INFOS, "r")) {
  print "Error opening file $INFOS for reading\n";
  exit;
}
while ($line = fgets($fic, 1000)) {
  // remove the end-of-line character if present
  $line = cutNewLineChar($line);
  // put the line into an array
  $infos = explode(":", $line);
  // retrieve the login
  $login = array_shift($info);
  // ignore the password
  array_shift($info);
  // create an entry in the dictionary
  $dico[$login] = $infos;
}
// close it
fclose($fic);

// use the dictionary
displayInfo($dico, "login10");
displayInfo($dico, "X");

// end
exit;

// --------------------------------------------------------------------------
function displayInfo($dico, $key) {
  // displays the value associated with key in the $dico dictionary if it exists
  if (isset($dico[$key])) {
    // value exists - is it an array?
    $value = $dico[$key];
    if (is_array($value)) {
      print "[$key," . join(":", $value) . "]\n";
    } else {
      // $value is not an array
      print "[$key,$value]\n";
    }
  } else {
    // $key is not a key in the $dico dictionary
    print "The key [$key] does not exist\n";
  }
}

// --------------------------------------------------------------------------
function cutNewLinechar($line) {
  // remove the end-of-line character from $line if it exists
  $L = strlen($line);  // line length
  while (substr($line, $L - 1, 1) == "\n" or substr($line, $L - 1, 1) == "\r") {
    $line = substr($line, 0, $L - 1);
    $L--;
  }
  // end
  return($line);
}

?>

The infos.txt file:

login0:pwd0:uid0:gid0:infos0:dir0:shell0
login1:pwd1:uid1:gid1:infos1:dir1:shell1
login2:pwd2:uid2:gid2:infos2:dir2:shell2
...
login98:pwd98:uid98:gid98:infos98:dir98:shell98
login99:pwd99:uid99:gid99:infos99:dir99:shell99

The results:

[login10,uid10:gid10:infos10:dir10:shell10]
The key [X] does not exist

Comments

  • Line 11: fopen(filename, "w") opens the file filename for writing (w = write). If the file does not exist, it is created. If it exists, its contents are cleared. If creation fails, fopen returns false. In the statement if (!$fic = fopen($INFOS, "w")) {…}, there are two successive operations: 1) $fic=fopen(..) 2) if( ! $fic) {...}
  • Line 18: fputs($fic,$string) writes string to the $fic file.
  • Line 20: fclose($fic) closes the $fic file.
  • line 25: fopen(filename, "r") opens the filename file for reading (r=read). If opening fails (the file does not exist), fopen returns a value of false.
  • line 29: fgets($fic,1000) reads the next line of the file, limited to 1000 characters. In the operation while ($line = fgets($fic, 1000)) {…}, there are two successive operations: 1) $line = fgets(...) 2) while ( ! $line). After the last character of the file has been read, the fgets function returns an empty string and the while loop stops.
  • Line 31: The fgets function reads a line of text, including the newline character. The cutNewLineChar function in lines 70–79 removes any newline character.
  • line 72: the strlen($string) function returns the number of characters in $string.
  • Line 73: The substr($line, $position, $size) function returns $size characters from $line, starting from character #$position, where the first character is #0. On Windows machines, the end-of-line marker is "\r\n". On Unix machines, it is the string "\n".
  • Line 35: The array_shift($array) function removes the first element from $array and returns it as the result.
  • line 37: the array_shift($array) function is used, but its result is ignored
  • Line 57: The is_array($variable) function returns true if $variable is an array, false otherwise.
  • Line 58: The join function does the same thing as the implode function we encountered earlier