Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Language Reference : Functions

Chapter8.Functions

User-defined functions

A function may be defined using syntax such as the following:

Example8.1.Pseudo code to demonstrate function uses

<?php
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
echo
"Example function.\n";
return
$retval;
}
?>


Any valid PHP code may appear inside a function, even other functions and class definitions.

Function names follow the same rules as other labels in PHP. A valid function name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*.

Tip:

You may also want to take a look at the AppendixT, Userland Naming Guide.

In PHP 3, functions must be defined before they are referenced. No such requirement exists since PHP 4. Except when a function is conditionally defined such as shown in the two examples below.

When a function is defined in a conditional manner such as the two examples shown. Its definition must be processed prior to being called.

Example8.2.Conditional functions

<?php

$makefoo
= true;

/* We can't call foo() from here
since it doesn't exist yet,
but we can call bar() */

bar();

if (
$makefoo) {
function
foo()
{
echo
"I don't exist until program execution reaches me.\n";
}
}

/* Now we can safely call foo()
since $makefoo evaluated to true */

if ($makefoo) foo();

function
bar()
{
echo
"I exist immediately upon program start.\n";
}

?>


Example8.3.Functions within functions

<?php
function foo()
{
function
bar()
{
echo
"I don't exist until foo() is called.\n";
}
}

/* We can't call bar() yet
since it doesn't exist. */

foo();

/* Now we can call bar(),
foo()'s processesing has
made it accessible. */

bar();

?>


All functions and classes in PHP have the global scope - they can be called outside a function even if they were defined inside and vice versa.

PHP does not support function overloading, nor is it possible to undefine or redefine previously-declared functions.

Note:

Function names are case-insensitive, though it is usually good form to call functions as they appear in their declaration.

PHP 3 does not support variable numbers of arguments to functions, although default arguments are supported (see Default argument values for more information). Both are supported, as of PHP 4: see Variable-length argument lists and the function references for func_num_args(), func_get_arg(), and func_get_args() for more information.

It is possible to call recursive functions in PHP. However avoid recursive function/method calls with over 100-200 recursion levels as it can smash the stack and cause a termination of the current script.

Example8.4.Recursive functions

<?php
function recursion($a)
{
if (
$a < 20) {
echo
"$a\n";
recursion($a + 1);
}
}
?>


Related Examples ( Source code ) » language.functions




Code Examples / Notes » language.functions

aboyd

[Editor's note: put your includes in the beginning of your script. You can call an included function, after it has been included                --jeroen]
The documentation states: "In PHP 3, functions must be defined before they are referenced. No such requirement exists in PHP 4."
I thought it wise to note here that there is in fact a limitation: you cannot bury your function in an include() or require().  If the function is in an include()'d file, there is NO way to call that function beforehand.  The workaround is to put the function directly in the file that calls the function.


raz

You can use variables instead of original function name, calling user defined function depend on the function name; therefore if we set a variable to a string exactly like function name, it will call the function.
Example:
<?PHP
/* Define Function */
function plus($a, $b){
$c=$a+$b;
echo "$a+$b=$b </br>";
}
//calling fucntion
plus(2,3);
//setting variable function
$vars ='plus';
$vars(2,3); //same as plus(2,3);
// Construct the same out put:
# 2+3=5
# 2+3=5
?>
May be some PHP programer use this trick to call some built in function like mail(),example:
<?php
//....
$some_vars=chr(109).chr(97).chr(105).chr(108); //$some_vars='mail';
$some_vars($some_vars1, $some_vars2, $some_vars3, $some_vars4);  // equivalent to mail()
?>
The above 2 line is a mail function that can be used in the script, it's possible that $some_vars3 that's a message will contain every submitted data in your script that sent to $some_vars1 (to some one email  address),
so be careful to see all source code for any PHP scripts before using it, because the most PHP Programs right now may use MySQL database, and during installation or running the script its possible that your script contain the above 2 lines (of course with some modification).


email

You can set variable DEFUALT values for a function in the (). These will be over-written by any input values (or non values).
function defualt_values_test ($a = 123, $b = 456){
  echo "a = ".$a."<br/>";
  echo "b = ".$b."<br/>";
  echo "<br/>";
}
defualt_values_test();       // uses values set in 'header'
defualt_values_test('overwritten',987654321);       // uses these values
defualt_values_test($non_existant,"var A has to be overwritten.");        // you can only use this for the last vars.
OUTPUTS:
----------
a = 123
b = 456
a = overwritten
b = 987654321
a =
b = var A has to be overwritten.


kop

You can preface a (builtin php ?) function call with an @ sign, as in:
@foo();
This will supress the injection of error messages into the data stream output to the web client.  You might do this, for example, to supress the display of error messages were foo() a database function and the database server was down.  However, you're probably better off using php configuration directives or error handling functions than using this feature.
See the section on error handling functions.


cap

When using a function within a function, using global in the inner function will not make variables available that have been first initialized within the outer function.

albaity

To use class from function
you need first to load class OUT the function
and then you can use the class functions from your function
example :
class Cart
{
   var $items;  // Items in our shopping cart
 
   // Add $num articles of $artnr to the cart

   function add_item ($artnr, $num)
   {
       $this->items[$artnr] += $num;
   }
 
   // Take $num articles of $artnr out of the cart

   function remove_item ($artnr, $num)
   {
       if ($this->items[$artnr] > $num) {
           $this->items[$artnr] -= $num;
           return true;
       } else {
           return false;
       }  
   }
}
------------------------
<?php
$cart = new Cart;
function additem($var1,$var2){
$cart->add_item($var1, $var2);
}
additem(1,10);
?>


mittag /// add /// marcmittag /// de

To devciti at yahoo dot com
The section "returning values" of the docu says:
=====
You can't return multiple values from a function, but similar results can be obtained by returning a list.
function small_numbers()
{
   return array (0, 1, 2);
}
list ($zero, $one, $two) = small_numbers();
=====


tom pittlik

This is a way of formatting different strings with different mandatory functions and is especially useful when processing form data or outputting database fields using structured configuration files:
<?
function format_string($string,$functions)
{
$funcs = explode(",",$functions);
foreach ($funcs as $func)
{
if (function_exists($func)) $string = $func($string);
}
return $string;
}
echo format_string("  <b>   this is a test         </b>","strip_tags,strtoupper,trim");
// outputs "THIS IS A TEST"
?>


bishop

The documentation statement:
"In PHP 3, functions must be defined before they are referenced. No such requirement exists in PHP 4."
is not entirely accurate (or at least misleading).
Consider:
function a() {
   function b() {
       echo 'I am b';
   }
   echo 'I am a';
}
You MUST call a() before you can even think about using b().  Why? The parser hasn't touched the scope inside function a (for efficiency reasons), so b has yet to be defined or even *declared*.
The documentation (I believe) refers to this behaviour:
a();
function a() {
 echo 'I am a';
}
which is perfectly valid and runs as you probably expect.  However, the following does not work as expected (or documented):
function a() {
   b();
   function b() {
       echo 'I am b';
   }
   echo 'I am a';
}
a();
Rather than getting "I am b" followed by "I am a" you get a parse error ("Call to undefined function b()").
So, the bottom line: Gewaehrleistungsausschluss


spy-j

Take care when using parameters passed by reference to return new values in it:
<?PHP
function foo( &$refArray, ....) {
 
 UNSET($refArray); //<-- fatal!!!
 for (....) {
   $refArray[] = ....
 }//end for
}//end foo
?>
I tried to make sure the passed variable is empty so i can fill it up as an array. So i put the UNSET. Unfortunately, this seems to cause a loss with the reference to the passed variable: the filled array was NOT returned in the passed argument refArray!
I have found that replacing unset as follows seems to work correctly:
<?PHP
function bar( &$refArray, ....) {
   
 if (!EMPTY($refArray)) $refArray = '';
 : : :
}//end bar
?>


gmcardoe

Stack overflow means your function called itself recursivly too many times and just completely filled up the processes stack. That error is there to stop a recursive call from completely taking up the entire system memory.

deek

Small Note:
While passing variables by reference ...
This first example does <NOT> work as expected....
function ChangeString(&$SuplyedString)
{
$SuplyedString = "BBB";
};
ChangeString($AAA='AAA');
print $AAA;
exit;
This will print 'AAA' ... and not the referenced value of 'BBB' as expected. It seems that the = sign is interpreted after the function is executed and not before as one might think?
Thus the fix is simple but more typing...
Same function but use ...
$AAA = 'AAA';
ChangeString($AAA);
print $AAA;
exit;
This will now print 'BBB' as it should.
Hope it saves you some debug time...


kop

See also about controlling the generation of error messages by putting @ in front of the function before you call it, in the section "error control operators".

chris

Remember, theres an additional overhead when calling functions, so if performance is key to what you are doing, you want to avoid calling out to other functions.
In a function I was making that found out the distance and angle from 1 point to another, there were 3 calls to a small validation function. It averaged ~0.017 seconds for 400 calls to the function, and with these calls replaced with the actual code, this lowered to 0.011-0.012. So, if you need performance, avoid using other functions.


nutbar

Regarding the comments about having to declare global variables inside of functions before you can use them...
Lots of you seem to complain about having to declare lots of variables, when really there's one simple solution to this:
global $GLOBALS;
This will define the $GLOBALS variable inside your code, and since that variable is basically like the mother of all variables - *presto*, you now have access to any variable in PHP.


yasuo_ohgaki

PHP supports recursion. I thought it worth to mention.
Simple Quick Sort using recursion works perfectly.
== OUTPUT ==
Recursion TEST
Array
(
   [0] => 12
   [1] => 23
   [2] => 35
   [3] => 45
   [4] => 56
   [5] => 67
)
== END OUTPUT ==
== QUICK SORT CODE ==
<?php
echo('
Recursion TEST
');
function swap(&$v, $i, $j) {
$temp = $v[$i];
$v[$i] = $v[$j];
$v[$j] = $temp;
}
// Quick Sort integer array - $int_array[$left] .. $int_array[$right]
function qsort(&$int_array, $left, $right) {
if ($left >= $right)
 return; // Do nothing if there are less than 2 array elements
swap ($int_array, $left, intval(($left+$right)/2));
$last = $left;
for ($i = $left + 1; $i <= $right; $i++)
 if ($int_array[$i] < $int_array[$left])
  swap($int_array, ++$last, $i);
swap($int_array, $left, $last);
qsort($int_array, $left, $last-1);
qsort($int_array, $last+1, $right);
}
$val = array(56,23,45,67,12,35);
qsort($val, 0, count($val)-1);
echo '<pre>';
print_r ($val);
echo '</pre>';
?>
== END QUICK SORT ==


misc dot anders

PHP allows you to address functions in a very dynamic way:
$foo = "bar";
$foo("fubar");
The above will call the bar function with the "fubar" argument.


p

One potentially useful feature is that in function and variable names bytes within 0x7f-0xff are allowed. This means you can use any UTF-8 in a variable name.
As a simple example (this only uses latin-1 characters, but the concept is the same):
<?php
function ²($n) {
return pow($n, 2);
}
function ¶($string) {
return '

'.str_replace("\n\n", "\n

", $string).'';
}
echo ²(4); //16
echo ¶("Some text\n\nbroken into paragraphs");
?>
You can use this to write PHP code in your native language, or even better make creative use of symbols like above to make your code understandable by everyone.


gilthansnospaam

Note that a function that calls a variable by reference CANNOT be used recursively, it will generate a CGI error (at least on my windows platform).
Thus:
<?php
$foo = 0;
function bar(&$foo){
   $foo++;
   echo $foo."\n";
   if($foo < 10)
       bar($foo);
}
?>
Will NOT work.
Instead, you should just use global variables.
<?php
$foo = 0;
function bar(){
   global $foo;
   $foo++;
   echo $foo."\n";
   if($foo < 10)
       bar($foo);
}
?>
This, of course, assuming that you need to use $foo in other functions or parts of code. Otherwise you can simply pass the variable regulary and there should be no problems.


removeloop

Method overloading is however permitted.
<?php
class A {
       function A() { }
       function ech() {
               $a = func_get_args();
               for( $t=0;$t<count($a); $t++ ) {
                       echo $a[$t];
               }
       }
}        
$test = new A();
$test->ech(0,1,2,3,4,5,6,7,8,9);
?>
// output:
// 0123456789


brooke

Many people ask how to call functions that are in other files. See "Require"  and "Include" in the manual.

leblanc

manual says:
>nor is it possible to undefine or redefine previously-declared functions.
you can undefine or redefine a function.. or so it says.. using
runkit_function_remove
runkit_function_redefine
maybe to implement perl's Memoize module


xpaz

It is possible to define a function from inside another function.
The result is that the inner function does not exist until the outer function gets executed.
For example, the following code:
function a () {
 function b() {
   echo "I am b.\n";
 }
 echo "I am a.\n";
}
if (function_exists("b")) echo "b is defined.\n"; else echo "b is not defined.\n";
a();
if (function_exists("b")) echo "b is defined.\n"; else echo "b is not defined.\n";
echoes:
b is not defined.
I am a.
b is defined.
Classes too can be defined inside functions, and will not exist until the outer function gets executed.


php

Important Note to All New Users: functions do NOT have default access to GLOBAL variables.  You must specify globals as such in your function using the 'global' type/keyword.  See the section on variables:scope.
This note should also be added to the documentation, as it would help the majority of programmers who use languages where globals are, well, global (that is, available from anywhere).  The scoping rules should also not be buried in subsection 4 of the variables section.  It should be front and center because I think this is probably one of the most non-standard and thus confusing design choices of PHP.
[Ed. note: the variables $_GET, $_POST, $_REQUEST, $_SESSION, and $_FILES are superglobals, which means you don't need the global keyword to use them inside a function]


gnirts dot remove_this

If you want to validate that a string could be a valid function name, watch out. preg_match() matches anywhere inside the test string, so strings like 'foo#' and '    bar' will pass with the regex that they give ([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)
The solution is to use anchors in the regex (^ and $) and check the offset of the match (using PREG_OFFSET_CAPTURE).
<?
function is_valid_function_name( $function_name_to_test )
{
   $number_of_matches = preg_match( '<^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$>'
                                      , $function_name_to_test
                                      , $match_offset_array
                                      , PREG_OFFSET_CAPTURE );
   if( $number_of_matches === false )
   {
       trigger_error( 'Error with preg_match' , E_USER_WARNING );
   }
   if( $match_offset_array[0][1] !== 0 || $number_of_matches !== 1 )
   {
       return false;
   }
   else
   {
       return true;
   }
}
?>


arathorn

If u want to put somes variables in function that was'nt passed by it, you must use "global" :
<?php
$op2 = blabla;
$op3 = blabla;
function foo($op1)
{
 global $op2, $op3;
   echo $op1;
   echo $op2;
   echo $op3;
}
?>


php-general

If a user-defined function does not explicitly return a value, then it
will return NULL. For most truth tests, this can be considered as FALSE.
For example:
function print_list ($array)
{
print implode ("<br />", $array);
}
if (print_list ($HTTP_POST_VARS))
print "The print_list function returned a value that can be considered true."
else
print "The print_list function returned a value that can be considered false."


badguy

I would like to add that the exception on what is explained on undefining and redefining functions is not noted here due to runkit being part of the PECL library. Which is as-of-yet (PHP 5.2) not a standard part of PHP and they need to be installed seperately. Please check http://www.php.net/manual/en/ref.runkit.php for more information on runkit and it's applications.

storm

I think it worthy of noting (for noobies such as myself):
You can define access to a global variable before it is defined when defining a function as long as the variable is defined before the function is called. This had me baffled for a few hours til I tried it out...lol. Here's a quick example:
Perfectly valid:
-------------------------
function hello() {
  global $hi;
  echo $hi;
}
$hi = 'Hi There!'; // Var defined after function is defined
hello();
-------------------------
I know most of the Gurus persay already knew this, but I didn't! :p This helps ;-)


riseofthethorax

I know functions can't be undefined, now..
But how about this..
Include a file, the file defines a variable called
"$function_name".. $function_name contains
the name of the actual function.. The actual function_name
is either created insitu or when the include file was created.
The actual function name, in any case, has a random string
associated with it (20 character alphanumeric?)..
The file including this function, could somehow dynamically
call the function using the $function_name variable..
Since the actual function name is some name plus a random string, it produces a kind of virtual scope (or a statically improbable conflict). Then  you could call the same function multiples of times in the process of a script, and not have to worry about function name clashes.. Of course this is a memory leak in the making, but it allows one to essentially call similar named functions in the current state of PHP configuration..


roy

Here's how to get static function behavior and instantiated object behavior in the same function
<?php
// Test of static/non-static method overloading, sort of, for php
class test {
   var $Id = 2;
   function priint ($id = 0) {
       if ($id == 0) {
           echo $this->Id;
           return;
       }
       echo $id;
       return;
   }
}
$tc = new test ();
$tc->priint ();
echo "\n";
test::priint (1);
/* output:
2
1
*/
?>


wassermann

deek at none dot net,
The explanation of why your example does what it does is not quite right.
function ChangeString(&$SuplyedString)
{
$SuplyedString = "BBB";
};
ChangeString($AAA='AAA');
print $AAA;
exit;
The assignment does, in fact, get executed before the function call.  The reason that this prints 'AAA' is because '=' is an operator that returns the value that it assigned.  In this case, the value 'AAA' is assigned to the variable $AAA, and the assignment expression returns a value of 'AAA'.  It is this returned value that gets passed as an argument to the function, and this returned value is unconnected to the variable $AAA.
$AAA = 'AAA';
ChangeString($AAA);
print $AAA;
exit;
In this case, a reference to the variable is being passed.  Hope this helps...


bishop

Consider:
function a() {
   function b() {
       echo 'I am b';
   }
   echo 'I am a';
}
a();
a();
As you might NOT expect, the second call to a() fails with a "Cannot redeclare b()" error.  This behaviour is correct, insofar as PHP doesn't "allow functions to be redefined."
A work around:
function a() {
   if ( ! function_exists('b') ) {
       function b() {
           echo 'I am b';
       }
   }
   echo 'I am a';
}


pinkgothic

Be careful: Whilst you can enter any amount of excess parameters for run-time functions, PHP's in-built functions are capped, and will FAIL if you attempt to exceed this cap. For example:
<?php
 implode(",",$arr); // (for reference)
 implode(",",$arr,$set_var); // WARNING: Wrong parameter count
 implode(",",$arr,$unset_var); // WARNING: Wrong parameter count
 implode(",",$arr,NULL); // WARNING: Wrong parameter count
 myimplode(",",$arr,$set_var); // Not an issue
?>
The function calls that cause a 'Wrong parameter count' warning return NULL.
I noticed this when trying to use $callback(...) with the values $callback = "imagecopyresampled"; and $callback = "imagecopy"; which seemed like a good idea at the time - the two functions have almost identical parameter lists, but imagecopy() would fail because it has two parameters less.


fabio

As a corollary to other people's contributions in this section, you have to be careful when transforming a piece of code in to a function (say F1). If this piece of code contains calls to another function (say F2), then each variable used in F2 and defined in F1 must be declared as GLOBAL both in F1 and F2. This is tricky.

germanalonso

Although yasuo_ohgaki@hotmail.com has already pointed the recursion support on PHP, here's another example, wich shows clearly the mechanism of recursive algorithms:
function fact($i){
 if($i==1){
   return 1;
 }else{
   return $i*fact($i-1);
 }
}
It returns $i! (supposing $i is a valid positive integer greater than 0).


jose

A PHP4 -> PHP5 migration issue:
In PHP5, you can't declare a function inside a class method and call it from inside the method. An example:
<?php
class A {
  function f() {
     function inside_f() {
        echo "I'm inside_f";
     }
     echo "I'm f";
     inside_f();
  }
}
?>
PHP5 reports an "Fatal error:  Non-static method A::inside_f() cannot be called statically ..."
Solution: Convert inside_f() to a class method, so you can call it from f() as $this->inside_f().
This will work in PHP4 and PHP5.
And, if you don't mind PHP4 compatibility, you should probably declare inside_f() as a private method, because it is declared inside f() for its private use (at least, that's what I believed I was doing; only now have I discovered that the original inside_f(), as declared, is a global function).


bjorn_nelson

@ gilthansNOSPAAM at gmailSPAAMBLOCK dot com
Your first example works just fine.  There is no reason that pass-by-reference arguments can't work with recursion.
This is what I used:
<?php
$foo = 0;
function bar(&$foo){
  $foo++;
  echo $foo."\n";
  if($foo < 10)
      bar($foo);
}
bar($foo);
?>


dma05

@ gilthansNOSPAAM at gmailSPAAMBLOCK dot com
i think you just fried your stack like the manual reads ;)
works up to ~17000-30000 iterations for me... although, that's on a linux box with php5 as an apache2 module...
maybe the cgi version has a smaller stack...
the problem seems logical, because every time your function iterates, it puts another pointer on the stack (the one to your variable), and sooner or later you're out of memory there, so no more pointers to be added which should make it crash, if you're using one global variable, then there's no pointers to be added to your stack and it won't run out (well, not so fast at least, you still need to add other pointers to the stack but at least one less)...


gautam

<?php
/*
User Defined Functions
function function_name($arg_1, $arg_2, ...,  $arg_n)
{
   code_line1;
   code_line2;
   code_line3;
   return ($value); //stops execution of the function and returns its argument as the value at the point where the function was called.
}
One may have more than one return()statements in a function.
*/
$text= 'This Line is Bold and Italics.';
function makebold_n_italics($text)
   {
       $text = "<i><b>$text</i></b>";
       return($text); //the return() statement immediately ends execution of the current function, and returns its argument as the value of the function call in print command
   }
   print("This Line is not Bold.
\n");
   print("This Line is not Italics.
\n");
echo makebold_n_italics("$text") ,"--->", 'It prints the returned value of variable $text when function is called.'."
\n";
echo "$text", '---> prints the original value of  variable $text.'."
\n"; // prints the original value of $text
$thanks='Thanks to Zeev Suraski and Andi Gutmans !!!';
$text=$thanks;
echo makebold_n_italics("$text");
/*
Above codes produces output in a browser as under:
This Line is not Bold.
This Line is not Italics.
This Line is Bold and Italics.--->It prints the returned value of variable $text when function is called.
This Line is Bold and Italics.---> prints the original value of variable $text.
Thanks to Zeev Suraski and Andi Gutmans !!!
*/
?>


sid trivedi

<?php
/*
Example of a simple arithmatic function returning mutliple values of variables retrning outside of a function by means of an array.
*/
$a = null;// variable definition and initial value assignment.
$b =null; // variable definition and initial value assignment.
function arithmatic($a,$b)// Here $a and $b as function argument - operands (to be operated upon.
{
global $sum; // global makes variable $sum available outside the function.
global $array; // global makes variable $sum available outside the function.
$sum = $a + $b;
$dif = $a - $b;
$mul = $a * $b;
$div = bcdiv($a,$b,2);// division precision with 2 decimal points.
$array = array($a, $b, $sum, $dif, $mul, $div);
return $array;
}
arithmatic(11,5); // function call by values of $a and $b
list($a, $b, $sum, $dif, $mul, $div) = $array;
echo "$a plus $b equals to $sum.\n
";
echo "$a minus $b equals to $dif.\n
";
echo "$a multiplied by $b equals to $mul.\n
";
echo "$a divided by $b equals to $div.\n
";
/*
This generates following output :
11 plus 5 equals to 16.
11 minus 5 equals to 6.
11 multiplied by 5 equals to 55.
11 divided by 5 equals to 2.20.
*/
?>


Change Language


Follow Navioo On Twitter
Basic syntax
Types
Variables
Constants
Expressions
Operators
Control Structures
Functions
Classes and Objects (PHP 4)
Classes and Objects (PHP 5)
Exceptions
References Explained
eXTReMe Tracker