ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


PHP Foundations

Advanced PHP Variables and Functions

05/17/2001

Today we'll discuss an advanced function concept called variable-length argument lists, and explain how to use dynamic function and variable names in PHP.

Variable-length argument lists

Until now, we have looked at parameters that are passed to custom functions to be statically defined (meaning once you decide on a set of parameters you are stuck with them until you change the declaration). Today, we'll discuss how you can create functions that define no parameters yet still function as expected when any number of parameters are passed to them. This concept of variable-length argument lists is made possible by a small family of built-in PHP functions: func_num_args(), func_get_arg(), and func_get_args().

The func_* function family

The func_* family of functions is a set of functions designed to run inside another function. Their purpose is to retrieve information regarding the arguments passed to the function in question. Because PHP allows you to pass parameters to functions that take no parameters in their definition, these functions can be used to create functions that take an unlimited number of parameters. For instance, consider the following snippet of code:

<?php
  function dynamic_args() {

  for($i = 0 ; $i < func_num_args(); $i++) {

  echo "Argument $i = ".func_get_arg($i)."<br />";

  }
  }

  dynamic_args("a", "b", "c", "d", "e");
?>

Compared to earlier examples of functions, the example above seems incorrect because we are defining a function that takes no parameters yet we are calling the function and passing five parameters to it. As stated earlier, PHP will allow us to pass extra parameters to our functions without error -- our real interest is in the function itself.

In the above function, we are using two of the func_* family commands to gather information regarding the parameters passed to dynamic_args(). First, we use func_num_args() to return the total number of arguments passed to dynamic_args(). In this case, the total number of parameters passed was five. Then, from within the for loop, we use the function func_get_args() and pass the index $i to it. When this is done, func_get_args() returns with the value of the parameter which equates to the index provided. This process continues until our for loop ends. The results of calling dynamic_args() with the parameters we specified would be the following output to the browser:

Argument 0 = a
Argument 1 = b
Argument 2 = c
Argument 3 = d
Argument 4 = e

As you can see, through the use of these very powerful functions available to us, we are able to create functions that can accept an unlimited number of parameters with ease. We can also use this method to create functions that require one parameter followed by an unlimited number of additional parameters as shown below:

<?php
  function implode_str($glue) {
    $string = "";

    for($i = 1; $i < func_num_args(); $i++) {
      $string .= $glue;
      $string .= func_get_arg($i);
    }
			
    return $string;

  }
	
  echo implode_str('-', 'This', 'is', 'a', 'test');
?>

In the above example, we define a function implode_str() that requires a single parameter $glue. Then, inside of our function we use the same function calls as we did in our earlier example to create a string $string based on the value of the extra arguments passed and the value of the $glue variable. Note that our for loop now starts off at 1 rather than 0. This is because we are declaring a single variable in our definition, so we will ignore it by only looking at variables passed after it that parameter. When the function is executed with the parameters above, its output will be -This-is-a-test. This is just one of the many ways to mix and match function definitions with the func_* family of functions to create variable-length argument lists.

Variable variables and function names

Note: Variable functions and variables are a potential security risk if used improperly. Before using variable function calls or variables, it is important to consider possible security holes that could arise from malicious user input.

Beyond dynamic parameters, PHP also supports the ability to call functions dynamically, as well as use variables dynamically. That is, we can write scripts that call functions and access variables without knowing the names of the functions or variables until the script starts executing. We'll start with how this can be accomplished with variables first, and then conclude with a similar syntax to be used for executing functions.

Variable variables

It is possible to access a particular variable in PHP without even knowing its name until after the script starts executing. This is done through a special variable syntax that is defined as the following: ${<var name>} where the variable name is either a constant (such as "foo") or another variable containing a string representation of the name. Sound confusing? Why don't we look at some examples to help make things more clear:

Also in PHP Foundations:

Using MySQL from PHP, Part 2

Using MySQL from PHP

MySQL Crash Course, Part 3

MySQL Crash Course, Part 2

MySQL Crash Course

<?php
  $foo = "This is the variable foo<br />";
  $bar = "This is the variable bar<br />";
  $foobar = "This is the variable foobar<br />";
  $foo_name = "foo";
  $bar_name = "bar";
	
  echo $foo;
  echo $bar;
  echo ${$foo_name};
  echo ${$bar_name};
  echo ${$foo_name.$bar_name};
?>

Above is what appears to be a fairly easy-to-understand script that simply echos different variables to the browser. However, the last three echo statements are referring to very strange looking variables. Consider the first of the last three echo statements. On this line, we are telling echo to print the variable whose name is contained within $foo_name. Because $foo_name's value is "foo", the echo statement will print the value of our PHP variable $foo to the browser. Although the second of the three is basically identical, the last statement is a little different. Here, we use the string concatenation operator '.' to combine the values of $foo_name and $bar_name to create the string "foobar" which we then use as the variable name for our last echo statement. The result of all of this is the following output:

This is the variable foo
This is the variable bar
This is the variable foo
This is the variable bar
This is the variable foobar

With this syntax, it is possible to write extremely complex scripts that are quite dynamic in nature with much less work then normally needed. Now that we have an idea on how to use variable variables, let's look at how to call functions based on the value of a variable.

Variable functions

Variable functions work on the same principal as variable variables. Basically given a variable containing a string representing a function in PHP, you can call the function simply by appending parentheses and any parameters to the end of the variable. For instance:

<?php
  function myfunc($msg) {
    echo $msg."<br />";
  }

  $func_name = "myfunc";
  $func_name("Hello, this is a test");
?>

will call the function myfunc() and pass our message "Hello, this is a test" to it. We accomplish this task by calling the function through the use of the variable $func_name that contains the actual name of the function myfunc.

Dynamic function creation

Beyond calling functions dynamically, it is also possible create functions dynamically. This can be done through the use of the create_function() function in PHP. The syntax of this function is as follows:

string create_function(string args, string code);

When called, we pass to the function two parameters. The first, args, is a string that contains the code that would normally go between the parentheses of a function declaration. The second parameter code is a string representation of actual PHP code that consists of what normally would be the body of a given function. When the create_function() is called, it creates the function as specified and returns a variable containing the name of that function that you can then use to call the function. Let's take a look at an example:

<?php
  // Normal function definition
  function my_normal_func($foo, $bar) {
    echo "Hi, PHP!";
  }
  // Dynamic function definition
  $func_name = create_function('$foo, $bar', 
               'echo "Hi, PHP!";' );
?>

In this example, we create two functions that are identical in output. In the first example, we declare prior to the script's execution and we name it my_normal_func(). In the second example, we create the function with a call to create_function(). When we execute the script, the function will be created and the name assigned to the function will be stored in the variable $func_name and will have the exact same code and parameters as the function we declared. This process can be useful in a number of circumstances (such as creating callback functions or data validation functions), and it is recommened that you read the manual entry on create_function() available on php.net for more information on how to use this function in everyday coding practice.

Final notes

With PHP, it is possible to create extremely complex, nearly self-creating programs that produce excellent results with a minimal amount of development time. As with almost every powerful tool, improper and careless use of dynamic programming can result in serious security leaks. Never base dynamic code on direct input from the user without first checking to ensure it contains no harmful or malicious code before creating functions or executing commands (particularly dynamic ones) based on it. Until next time -- happy coding!

John Coggeshall is a a PHP consultant and author who started losing sleep over PHP around five years ago.


Read more PHP Foundations columns.

Return to the PHP DevCenter.

Copyright © 2009 O'Reilly Media, Inc.