Basic Code Reuse: Functions


It never fails that, at some point in our programming, we begin to look for a way to better organize our code. Perhaps we would like to make our code easier to read and more logically structured, or perhaps we find ourselves writing the same chunk of code too often. In the latter case, we would be much happier if we could reduce the chunk to a simple line of code that does the same thing in all locations. As in other languages, PHP provides the ability to define and implement functions. However, PHPs have a few differences that make them quite flexible and powerful.

Defining and Calling Functions

The way to define a function in PHP is quite simple:

 <?php    function some_function_name([parameter list goes here ...])    {      [body of function ...]    } ?> 

The function keyword tells PHP that this is a function. What follows is the name of the function, which can be any combination of alphanumeric characters and underscores, as long as it does not begin with a number. Letters in the name can be any 8-bit characters understood by the operating system, including extended ASCII characters and multi-byte characters. You are encouraged to be extremely careful when using extended characters in your code; even though they may work in the simple cases, you may run into problems later with file formats and character set issues.

 <?php   function booo_spooky()   {     echo "I am booo_spooky.  This name is okay!<br/>\n";   }   function ____333434343434334343()   {     echo <<<DONE       I am ____333434343434334343. This is an awfully        unreadable function name.  But it is valid. DONE;    }   //   // This next function name generates:   //   // Parse error: syntax error, unexpected T_LNUMBER,    // expecting T_STRING in    // /home/httpd/www/phpwebapps/src/chapter03/playing.php    //    on line 55   //   // Function names cannot start with numbers   //   function 234letters()   {     echo "I am not valid<br/>\n";   }   //   // Extended characters are ok.   //   function grüç_dich()   {     echo "Extended Characters are ok, but be careful!<br/>\n";   }   //   // REALLY extended characters are ok, too!!  Your file will   // have to be saved in a Unicode format though,   // such as UTF-8. (See Chapter 6.)   function ()   {     echo <<<EOT       Even Japanese characters are ok in function names, but        they are probably best avoided. EOT;   } ?> 

After the function name comes the parameter list and then the body of the function. Unlike some of the control structures, such as the if statement, while statements, or for loops (which can contain either a single statement with a semicolon or a block of code), the body of a function must begin and end with brackets ({}).The code inside this body is processed and executed whenever the function is called.

Only one version of a function with a given name can exist at any time. The feature seen in some other languages where you can declare a function with the same name but different parameter lists multiple times does not exist in PHP.

Calling functions is also straightforward. You simply type the name of the function and enclose any parameters in parentheses after it. If there are no parameters, then you include the parentheses with nothing between them. Although the calling of functions in PHP is case-insensitive, we encourage you to use the same casing that the original function definition used for the sake of readability and maintainability.

 <?php   generate_left_menu_bar();   GeNeRaTe_LeFt_MEnu_BaR();  // ok too, but not recommended!!   process_user_information($current_user, "new user", 65.0);   generate_copyright_notices();   generate_left_menu_bar;    // NOT valid -- must include ()!! ?> 

Stopping Execution Within a Function

At any point within a function, you can stop the execution of code by using the return statement. This tells PHP to stop executing code in the current function and return to the caller.

 <?php   function work_work_work()   {     $dow = date('l');     if ($dow == 'Saturday' or $dow == 'Sunday')     {       // no work on weekends.       return;     }     // work hard     work_harder();   } ?> 

When the work_work_work function is called on a Saturday or Sunday, it simply returns from the function to the caller and executes nothing further.

Passing Parameters to Functions

You can customise the way your functions perform by allowing them to receive information from the caller, typically called parameters.

Basic Syntax

To define a function that accepts parameters when called, include their names, separated by commas, between the parentheses when defining the function. (The last one requires no comma after it.)

 <?php   function my_new_function($param1, $param2, $param3, $param4)   {     echo <<<DONE       You passed in: <br/>       \$param1:  $param1 <br/>       \$param2:  $param2 <br/>       \$param3:  $param3 <br/>       \$param4:  $param4 <br/> DONE;   } ?> 

To pass parameters to a function, include the parameter values, separated by commas, between the parentheses when calling it. You can pass in any valid expression for each parameter, whether it is a variable, constant value, the result of evaluating operators, or even function calls:

 <?php   //   // call my new function with some values.   //   my_new_function($userName, 6.22e23, pi(), $a or $b); ?> 

The scope (areas of code in which the use is valid) of any parameter is only local to the function that declares it. If one happens to have the same name of a variable at a different scoping level (the top-level script, for example), the parameter "masks" that variable, which does not result in changes to the variable outside of the function.

Passing by Reference

By default, only the value of a variable is passed in to a function. Thus, any changes to this parameter or variable are local to the function only.

 <?php   $x = 10;   echo "\$x is: $x<br/>\n";   change_parameter_value($x);   function change_parameter_value($param1)   {     $param1 = 20;   }   echo "\$x is: $x<br/>\n"; ?> 

The previous script will print

 $x is: 10 $x is: 10 

If your goal is to have a function actually modify a variable being passed to it instead of merely working with a copy of its value, you can use the ability to pass parameters by reference. This is done with the ampersand (&) character, which is prepended to the parameter both in the function definition and at the location where the function is actually called.

 <?php   function increment_variable(&$increment_me)   {     if (is_int($increment_me) || is_float($increment_me))     {       $increment_me += 1;     }   }   $x = 20.5;   echo "\$x is: $x <br/>\n";          // prints 20.5   increment_variable(&$x);   echo "\$x is now: $x <br/>\n";      // prints 21.5 ?> 

You can only pass variables to the increment_variable function by reference, since the function will try to modify the underlying value. This means that you cannot pass a constant (whether it is a simple number or a reference to a predefined constant), since the function is unable to change the underlying storage location.

 <?php    increment_variable(123); ?> 

The output of this script would be

 Fatal error: Only variables can be passed by reference   in c:\Inetpub\wwwroot\phpwebapps\src\chapter03\examples.php   on line 328 

Attempting to put an ampersand (&) in front of anything other than a variable also generates a fatal syntax error when running the script.

One "fly in the ointment" of by reference parameters is that some built-in PHP functions accept parameters as by reference without requiring you to prefix them with the & character. (See Chapter 5 for some examples.)

Default Argument Values

For those times when you expect the value of a parameter to predominately have a certain value, you can save yourself the hassle of entering it each time by using a feature called default argument values or optional parameters.

You can assign a default value for any number of parameters by simply assigning a value in the parameter list in the function declaration.

 <?php   function perform_sort($arrayData, $param2 = "qsort")   {     switch ($param)     {       case "qsort":         qsort($arrayData);         break;       case "insertion":         insertion_sort($arrayData);         break;       default:         bubble_sort($arrayData);         break;       }   } ?> 

To call a function with default parameter values, you can choose to simply omit those provided parameter values, provided there are no parameters after that without default values.

 <?php   $arrayData = get_data_from_somewhere();   perform_sort($arrayData);               // defaults to qsort   perform_sort($arrayData, "insertion");  // uses insertion sort ?> 

While PHP technically allows you to mix optional parameter and nonoptional parameters when you are defining a function, it makes trying to call a function a bit more complicated.

 <?php   function def_params($p1 = "moo", $p2, $p3, $p4 = "cow")   {     echo <<<DONE     \$p1 = $p1 <br/>     \$p2 = $p2 <br/>     \$p3 = $p3 <br/>     \$p4 = $p4 <br/> DONE;   } ?> 

Since the second and third parameters are always required, so is the first. Simply skipping the first parameter while specifying the second and third

 def_params(1, 2); 

generates the following output and warning:

 Warning: Missing argument 3 for def_params() in    /home/httpd/www/phpwebapps/src/chapter03/playing.php    on line 366 $p1 = 1 $p2 = 2 $p3 = $p4 = cow 

In general, parameters with default values should be kept at the end of the parameter list, and used sparingly.

Variable Numbers of Parameters

PHP has the ability to pass to functions completely arbitrary numbers of parameters and helper functions to handle such situations. To define a function as accepting a variable number of parameters, you define the function with no parameters and then use the functions func_num_args, func_get_arg, and func_get_args to fetch the values of the parameters.

As you might expect, func_num_args tells you how many parameters were passed to this particular function call. func_get_arg returns the parameter at the given index (starting at 0 and going to func_num_args 1), while func_get_args simply returns all of the parameters in an array.

 <?php   function print_parameter_values()   {     $all_parameters = func_get_args();     foreach ($all_parameters as $index => $value)     {       echo "Parameter $index has the value: $value<br/>\n";     }     echo "-----<br/>\n";   }   print_parameter_values(1, 2, 3, "fish");   print_parameter_values(); ?> 

The previous script has the output

 Parameter 0 has the value: 1 Parameter 1 has the value: 2 Parameter 2 has the value: 3 Parameter 3 has the value: fish ----- ----- 

Many of the built-in functions provided by PHP use default argument values to great effect. For example, the date function takes as its first argument the way you wish to format the output date. The second parameter is optional. If you specify a timestamp value, it uses that to generate the string. Otherwise, it uses the current date and time to generate its output.

 <?php   $d1 = date('l');                 // Sunday   $d2 = date('l', 123435678);       // Thursday ?> 

Returning Values from a Function

Unlike some languages, which distinguish between subroutines that simply execute some code before exiting and functions that execute some code and then return a value to the caller, all of PHP's functions have a value associated with them upon returning to the caller. For those functions where there is no explicitly given return value, its value is NULL:

 <?php   function does_nothing()   {   }   $ret = does_nothing();   echo '$ret: ' . (is_null($ret) ? '(null)' : $ret) . "<br/>"; ?> 

The previous script always prints $ret: (null).

However, we frequently want to have our function return a value other than NULL. In this case, we make use of the return keyword in PHP. When we use it, we associate an expression with it, the value of which it passes back to the caller when exiting the function. This expression value can be anything with a value, such as a constant, a variable, or a function call.

 <?php   function is_even_number($number)   {     if (($number % 2) == 0)       return TRUE;     else       return FALSE;   } ?> 

For those cases where you want to return multiple values from a function, it is convenient to pass the results back as an array.

 <?php   function get_username_pwd($userid)   {     //     // these two functions are fictional     //     $username = get_name_from_id($userid);     $password = get_pwd_from_id($userid);     return array("UserName" => $username,                   "Password" => $password);   } ?> 

Variable Scope Inside of Functions

As we mentioned in "Variable Scope" in Chapter 2, "The PHP Language," three classes of variables exist. These classes are divided by their "sphere of influence," or scope.

Function Level Variables

There will be times when, to do our work, we will want to declare and use new variables within a function. These local variables can be declared inside of functions just by assigning a value to them. However, what is different between these and other variables in your script is that they are valid only within the function in which they are declared. In fact, each time the function is executed, any old values that the variable might have had are forgotten.

 <?php   $x = 10;   function print_some_number()   {     $y = 200;     echo $y;   }   print_some_number();   echo $x;   echo $y; ?> 

The previous script prints

 200 Notice: Undefined variable: y in D:\WebApps\WWW\test.php         on line 11 10 

Parameters for a function have the same scoping rules. They are valid only within the function in which they are declared, and their values are not remembered between invocations of the function. The only significant difference between them and other local variables is that they have their values assigned to them through the act of calling the function.

Static Variables

Variables with the keyword static prefixed to them retain their values between function invocations during the execution of the current script. If a value is assigned to them when they are declared, PHP only performs this assignment the first time it sees the variable while running the current script:

 <?php   function increment_me()   {     // the value is set to 10 only once.     static $incr = 10;     $incr++;     echo "$incr<br/>\n";   }   increment_me();   increment_me();   increment_me(); ?> 

The previous script prints

 11 12 13 

However, as we mentioned in "Variable Lifetime" in Chapter 2, PHP remembers nothing between script invocations, so the value of $incr is reset to 10 each time the previous script is run.

Variables Declared Within Your Script ("Global Variables")

For those variables that you declare at the script level (also called global variables), PHP is a bit different from some other languages in that they are not, by default, accessible from within functions. Note:

 <?php   $name = "Fatima";   echo "\$name:  $name<br/>\n";   function set_name($new_name)   {     echo "\$name:  $name<br/>\n";     $name = $new_name;   }   set_name("Giorgio");   echo "\$name:  $name<br/>\n"; ?> 

This code snippet prints the following output:

 $name: Fatima Notice: Undefined variable: name in /home/httpd/www/phpwebapps/src/chapter03/playing.php on line 26 $name: $name: Fatima 

This output is seen because the variable $name inside of the set_name function is a local variable that masks the outer script level variable. A warning is therefore printed since $name is undefined when the echo function is called within the set_name function.

To access script level variables from within a function, you need to declare them within the function by using the global keyword along with the variable names. You can also specify multiple global variables in one statement with the global keyword. By doing this, you can access variable values and know that any changes to the values will be remembered when the function exits.

 <?php   $name = "Fatima";   echo "\$name:  $name<br/>\n";   function set_name($new_name)   {     global $name;         // we are now using the global $name     echo "\$name:  $name<br/>\n";     $name = $new_name;   }   set_name("Giorgio");   echo "\$name:  $name<br/>\n"; ?> 

The snippet of code now emits

 $name: Fatima $name: Fatima $name: Giorgio 

This is what we had intended the first time we ran the script. We should take a moment here to note that "global" is not the optimal word to describe script level variables, since they are not remembered between invocations of your script. When our scripts are run, they are reinitialized as unset until an assignment statement gives them a value. While they operate at a much broader scoping level than those variables you assign within functions, they still have very limited lifetimes.

Avoid changing too many global variables within your functionsit will become difficult to read, and understanding the side effects of any given function call will also become challenging.

Superglobals

As we mentioned in "Variable Scope" (Chapter 2), superglobals are accessible from anywhere within your PHP scripts. Many of these are predefined variables provided by PHP, although not all predefined variables are superglobals. We will point out superglobals as we encounter them in this book.

Function Scope and Availability

Functions that you define in your script, no matter whether the call to them is before or after the definition, are available from anywhere within it.

 <?php   //   // this is okay -- prints out "Hello There!"   //   print_out_hello();   function print_out_hello()   {     echo "Hello There!<br/>\n";   }   //   // also okay!   //   print_out_hello(); ?> 

With function scope, PHP allows you to define functions within other functions and even within code blocks associated with control structures.

 <?php   function set_user_prefs_fn($user_type)   {     if ($user_type == "EXPERIENCED")     {       function get_user_prefs($user)       {         return array("Shell" => $user["shell"],                      "Editor" => $user["editor"],                      "Terminal" => $user["term"]);       }     }     else     {       function get_user_prefs($user)       {         return array("Preferred GUI" => $user["gui"]);       }     }   }   set_user_prefs_fn("BASIC");   //   // we'll have an array with a "Preferred GUI" key/value pair.   //   $local_prefs = get_user_prefs($current_user); ?> 

In the previous example, we would not be able to call the get_user_prefs function until we had first called the set_user_prefs_fn function. The latter function (depending on the value of a parameter passed to it) determines which version of the get_user_prefs function will be used. Earlier, we gave it a value of "BASIC", which implies that the second version of get_user_prefs should be used.

Now observe what happens when we call set_user_prefs_fn again:

 Fatal error: Cannot redeclare get_user_prefs() (previously   declared in    /home/httpd/www/phpwebapps/src/chapter03/example.php:98) in   /home/httpd/www/phpwebapps/src/chapter03/example.php on line 96 

Once a function has been defined within another function, control structure, or other file, it is available everywhere within the script and cannot be defined again. To see if a function has been defined, call function_exists.

 <?php   function set_data_connect_function($dbtype)   {     if (!function_exists("data_connect"))     {       if ($dbtype == "LOCAL")       {         function data_connect()         {            // etc         }       }       else       {         function data_connect()         {            // etc         }       }     }   } ?> 

Functions as Variables

In keeping with its theme of flexibility and ease of use, PHP offers you the ability to use functions as variables. In short, if PHP sees parentheses after a variable name (where the variable is a string), it tries to find a function with that name contained in the value of that variable and executes it. This can prove useful when you want to change which function gets called depending on the circumstances.

If we wanted to have a message logging function that wrote a notification message sometimes to a file, to the browser, or to a network server, we could write code similar to the following:

 <?php   function Log_to_File($message)   {     // open file and write message   }   function Log_to_Browser($message)   {     // output using echo or print functions   }   function Log_to_Network($message)   {     // connect to server and print message   }   //   // we're debugging now, so we'll just write to the screen   //   $log_type = "Log_to_Browser";   //   // now, throughout the rest of our code, we can just call   // $log_type(message).   //   $log_type("beginning debug output"); ?> 

Even though language constructs appear to operate largely as functions, PHP contains a number of them that cannot be used as variable functions. Notable examples of these constructs are the echo, print, var_dump, print_r, isset, unset, is_null, and is_type methods.




Core Web Application Development With PHP And MYSQL
Core Web Application Development with PHP and MySQL
ISBN: 0131867164
EAN: 2147483647
Year: 2005
Pages: 255

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net