dismiss Step into the future! Click here to switch to the beta php.net site
downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | conferences | my php.net

search for in the

get_defined_functions> <func_num_args
[edit] Last updated: Fri, 27 Sep 2013

view this page in

function_exists

(PHP 4, PHP 5)

function_existsReturn TRUE if the given function has been defined

说明

bool function_exists ( string $function_name )

Checks the list of defined functions, both built-in (internal) and user-defined, for function_name.

参数

function_name

The function name, as a string.

返回值

Returns TRUE if function_name exists and is a function, FALSE otherwise.

Note:

This function will return FALSE for constructs, such as include_once and echo.

范例

Example #1 function_exists() example

<?php
if (function_exists('imap_open')) {
    echo 
"IMAP functions are available.<br />\n";
} else {
    echo 
"IMAP functions are not available.<br />\n";
}
?>

注释

Note:

A function name may exist even if the function itself is unusable due to configuration or compiling options (with the image functions being an example).

参见

  • method_exists() - 检查类的方法是否存在
  • is_callable() - 检测参数是否为合法的可调用结构
  • get_defined_functions() - Returns an array of all defined functions
  • class_exists() - 检查类是否已定义
  • extension_loaded() - 检查一个扩展是否已经加载



get_defined_functions> <func_num_args
[edit] Last updated: Fri, 27 Sep 2013
 
add a note add a note User Contributed Notes function_exists - [21 notes]
up
down
6
kitchin
1 year ago
You can use this function to conditionally define functions, see: http://php.net/manual/en/functions.user-defined.php

For instance Wordpress uses it to make functions "pluggable." If a plugin has already defined a pluggable function, then the WP code knows not to try to redefine it.

But function_exists() will always return true unless you wrap any later function definition in a conditional clause, like if(){...}. This is a subtle matter in PHP parsing. Some examples:

<?php
if (function_exists('foo')) {
  print
"foo defined\\n";
} else {
  print
"foo not defined\\n";
}
function
foo() {}

if (
function_exists('bar')) {
  print
"bar defined\\n";
} else {
  print
"defining bar\\n";
  function
bar() {}
}
print
"calling bar\\n";
bar(); // ok to call function conditionally defined earlier

print "calling baz\\n";
baz(); // ok to call function unconditionally defined later
function baz() {}

qux(); // NOT ok to call function conditionally defined later
if (!function_exists('qux')) {
  function
qux() {}
}
?>
Prints:
  foo defined
  defining bar
  calling bar
  calling baz
  PHP Fatal error: Call to undefined function qux()

Any oddities are probably due to the order in which you include/require files.
up
down
3
php at fluidthoughts dot com
5 years ago
function_exists returns false on NULL and empty string:

<?php
       
if (function_exists('')) {
                echo
"empty string function exists\n";
        }

        if (
function_exists(NULL)) {
                echo
"NULL function exists\n";
        }
?>

Neither of the echo statements happen when I run this.
up
down
1
eddiec at stararcher dot com
6 years ago
Note that function_exists will return TRUE in the following situation, presumably because the function "testfunc" was defined when the script was PARSED/ITERPRETED, before the function_exists call was made at RUNTIME:

<?php
if (function_exists('testfunc')) return;
function
testfunc() { }
?>

So, this construction is not useful for preventing testfunc from being multiply defined if the script is muliply included or required.

However, the following construction DOES work to prevent multiple defines of testfunc:

<?php
if (!function_exists('testfunc')) {
  function
testfunc() { }
}
?>

CONTRAST this with similar uses of defined() which is completely runtime evaluated.  These both work:

<?php
if (defined('testfunc_defined')) return;
define('testfunc_defined', 1);
function
testfunc() { }
?>

AND...

<?php
if (!defined('testfunc_defined')) {
define('testfunc_defined', 1);
function
testfunc() { }
}
up
down
1
brooklynphil at hotmail dot com
6 years ago
to bob at thethirdshift dot net
regarding is_callable vs function_exists.

using your code
is_callable = TRUE, function_exists = FALSE

Did 10000 is_callables in 0.0443360805511 seconds
Did 10000 function_exists in 0.0111110210419 seconds

then we replace
is_callable(array('test','test'));
with
$callarray = array('test','test'); // place this outside for-loop
is_callable($callarray);

is_callable = TRUE, function_exists = FALSE

Did 10000 is_callables in 0.0314660072327 seconds
Did 10000 function_exists in 0.0120670795441 seconds

then we replace
is_callable(array('test','test'));
with
is_callable('test','test');

is_callable = TRUE, function_exists = FALSE

Did 10000 is_callables in 0.00991606712341 seconds
Did 10000 function_exists in 0.0113790035248 seconds

I hope you can see that loop-testing functions is not so simple. :)
up
down
2
dieter at edarta dot be
6 years ago
to brooklynphil at hotmail dot com:

Your post is misleading, namely the 3rd and last speedtest you describe is an unfair comparison:

<?php
is_callable
('test','test');
?>

The value of the 2nd parameter $syntax_only is 'test' and this evaluates to boolean true. In other words, this is exactly the same as calling the function like this:

<?php
is_callable
('test',true);
?>

Of course this will be faster because is_callable only does a very basic syntaxcheck. From the documentation: 'It will only reject simple variables that are not strings, or an array that does not have a valid structure to be used as a callback.'

If you omit this erroneous 3rd test, then according to your examples function_exists is 2 to 4 times faster.

I hope you can see that loop-testing functions is not so simple. :)

rtfm
up
down
1
admin at gk-root dot com
1 year ago
// If you want to chack if the function is enabled or disable in php.ini you can use this function:

<?php
function func_enabled($func) {
   
$disabled = explode(',', ini_get('disable_functions'));
    foreach (
$disabled as $disableFunction) {
       
$is_disabled[] = trim($disableFunction);
    }
    if (
in_array($func,$is_disabled)) {
       
$it_is_disabled["m"] = $func.'() has been disabled for security reasons in php.ini';
       
$it_is_disabled["s"] = 0;
    } else {
       
$it_is_disabled["m"] = $func.'() is allow to use';
       
$it_is_disabled["s"] = 1;
    }
    return
$it_is_disabled;
}
?>

// An example of how to use:

<?php
$if_is_disabled
= func_enabled('exec'); // return Arrey
echo $if_is_disabled["m"]; // return text value
echo '<br/>';
echo
$if_is_disabled["s"]; // return 1 or 0
?>
up
down
1
bob at thethirdshift dot net
9 years ago
I, too, was wondering whether is_callable or function exists is faster when checking class methods.  So, I setup the following test:

<?php
function doTimes($start, $end)
  {
   
$start_time = explode (" ", $start);
   
$start_time = $start_time[1] + $start_time[0];
   
$end_time = explode (" ", $end);
   
$end_time = $end_time[1] + $end_time[0];
   
$time = $end_time - $start_time;
    return
$time;
  }

class
test
 
{
      function
test()
      {
          return
true;
      }
  }
 
$callableIsTrue = false;
$startIsCallable = microtime();
for(
$i = 0; $i < 10000; $i++)
  {
      if(
is_callable(array('test', 'test'))) { $callableIsTrue = true; }
  }
$endIsCallable = microtime();

$existsIsTrue = false;
$startExists = microtime();
for(
$i = 0; $i < 10000; $i++)
  {
      if(
function_exists('test::test')) { $existsIsTrue = true; }
  }
$endExists = microtime();

$timeIsCallable = doTimes($startIsCallable, $endIsCallable);
$timeExists     = doTimes($startExists, $endExists);

echo
"<b>is_callable = ".($callableIsTrue ? "TRUE" : "FALSE")."</b>, \n";
echo
"<b>function_exists = ".($existsIsTrue ? "TRUE" : "FALSE")."</b><br>\n";

echo
"<br>Did 10000 is_callables in ".$timeIsCallable." seconds";
echo
"<br>Did 10000 function_exists in ".$timeExists." seconds";
?>

This gives the output :

is_callable = TRUE, function_exists = FALSE

Did 10000 is_callables in 0.0640790462494 seconds
Did 10000 function_exists in 0.0304429531097 seconds

So the fact that function_exists is twice as fast is slightly over shadowed by the fact that it doesn't work on class methods, at least not as far as I can tell.
up
down
0
Michael dot Bond at mail dot wvu dot edu
2 years ago
a more complete function_exists that checks for the following:

functions (php and user defined)
class methods
 * as strings in the sense of "class::method" or "class->method"
 * passing a class name or object, as well as the method
language constructs (echo, print, etc ..)

<?php
function functionExists($param1,$param2=null) {
   
   
$langConstructs = array("die",
                           
"echo", "empty", "exit", "eval",
                           
"include", "include_once", "isset",
                           
"list",
                           
"print",
                           
"require", "require_once",
                           
"unset"
                           
);
   
   
// 2 params provided, assume class
   
if (!is_null($param2)) {
        return(
method_exists($param1,$param2));
    }
   
   
// Ignore everything that isn't a string, from this point on
   
if (!is_string($param1)) {
        return(
FALSE);
    }
   
   
// check if function exists
   
if (function_exists($param1) === TRUE) {
        return(
TRUE);
    }
   
   
// Check to see if it is an object being passed as a string.
    // if so, assume object
   
$items = explode("::",$param1);
    if (
count($items) == 2) {
        return(
method_exists($items[0],$items[1]));
    }
   
   
$items = explode("->",$param1);
    if (
count($items) == 2) {
        return(
method_exists($items[0],$items[1]));
    }
   
   
// check to see if it is a language construct
   
if (in_array($param1,$langConstructs)) {
        return(
TRUE);
    }
   
    return(
FALSE);
}
?>
up
down
0
zach at bygeekz dot com
5 years ago
to php at fluidthoughts dot com

you aren't comparing against false, that if compares against true, so it's going to return that, as false != true
true being 1, True, (bool)True, etc.
false being 0, False, Null, etc
<?php

$foo
=null;
if (
$foo) { echo 'yay'; } //does not echo yay, because null is not True

$foo=false;
if (
$foo) { echo 'yay'; } //does not echo yay, because false is not True

$foo=null;
if (!
$foo) { echo 'yay'; } //echoes yay!

$foo=false;
if (!
$foo) { echo 'yay'; } //echoes yay!

?>

This..
<?php
   
if (!function_exists('')) {
                echo
"empty string function doesnt exist as compared as negative\n";
        }

        if (!
function_exists(NULL)) {
                echo
"NULL function doesnt exist as compared as negative\n";
        }
?>
Works.

Alternatively, to enter upon existance..

Use your code. Since they dont exist, it wont enter..
up
down
0
webmaster at mamo-net dot de
6 years ago
If you use suhosin.executor.func.blacklist instead of disabled_functions in your php.ini, function_exists will return true for a disabled function. I used this to have the same beahviour with suhosin.executor.func.blacklist and disabled_functions:

<?php
function suhosin_function_exists($func) {
    if (
extension_loaded('suhosin')) {
       
$suhosin = @ini_get("suhosin.executor.func.blacklist");
        if (empty(
$suhosin) == false) {
           
$suhosin = explode(',', $suhosin);
           
$suhosin = array_map('trim', $suhosin);
           
$suhosin = array_map('strtolower', $suhosin);
            return (
function_exists($func) == true && array_search($func, $suhosin) === false);
        }
    }
    return
function_exists($func);
}
?>
up
down
0
White-Gandalf
6 years ago
I stumbled over the same problem as "eddiec" (users not able or not willing to use "_once"-suffixes).

A possible alternative explanation for the behavior:

If a file is included, it is possibly parsed every include-time.(?)
While parsing, every function in global scope is tried to register. THIS gets wrong, when multiple times included, and it produces an error.

If functions are defined within block scopes, their registration seems to be delayed until execution of such a block. Thus, not the function "function_exists" functions wrong, but simply the philosophy of the interpreter produces such results.

Thus, the same effect can be achieved by simply putting block braces around the contents of an include_once file:

if (function_exists('function_in_question')) return;
{
    function function_in_question(...)
    {
        ...
    }
    ...other stuff
}

...which is equivalent to...

if (!function_exists('function_in_question'))
{
    function function_in_question(...)
    {
        ...
    }
    ...other stuff
}
up
down
0
Dan
7 years ago
I would like to comment on the following post:

A note of caution: function_exists() appears to be case-insensitive (at least as of PHP 4.3.8).  e.g.:

<?php
  
function MyCasedFunction() {
       return
true;
   }

  
// Will return true, even though casing is "wrong"
  
if (function_exists("mYcAsEdFuNcTiOn"))
       echo
"I see it!";
?>

I believe that function calls itself are case insensitve, so this function is returning a valid truth. PHP doesn't care about cases.
up
down
0
andi at splitbrain dot org
7 years ago
function_exists will return false for functions disabled with the disable_functions ini directive. However those functions are still declared so trying to define them yourself will fail.

<?php
if(!function_exists('readfile')){
  function
readfile($file){
   
$handle=@fopen($cache,"r");
    echo @
fread($handle,filesize($file));
    @
fclose($handle);
  }
}
?>

The above will issue a "Cannot redeclare readfile()" fatal error if readfile was disabled with disable_functions.
up
down
0
neelam_ab2003 at yahoo dot co dot in
7 years ago
<?php
/*PHP doesn't Support nested functions. I have tried following in PHP_VERSION - 5.1.2*/

function A(){}

function
B(){
    function
C(){
        function
D(){}
    }
}

IsFunctionExist('A');
IsFunctionExist('B');
IsFunctionExist('C');
IsFunctionExist('D');

function
IsFunctionExist($funcName){
    echo
function_exists($funcName)?" $funcName exist <br>":" $funcName doesn't exist <br>";
}
?>

/*O U T P U T
A exist
B exist
C doesn't exist
D doesn't exist
*/
up
down
0
chaumo
8 years ago
to avoid direct calls this can be better than function_exists
in the parent file:
<?php
define
("IN_MODULE",true);
?>
and in the target file:
<?php
if(!defined("IN_MODULE")) die("Can't access the file directly");
?>
up
down
0
fili at fili dot nl
8 years ago
To prevent direct calls to included files i use the following technique.

In the main file create an empty function with a random name. Like so:

<?php
function hjudejdjiwe() { return true; }
?>

Then check for the existence of this function within your include:

<?php
if (!function_exists('hjudejdjiwe')) { die('!'); }
?>

Simple but effective.
up
down
0
ckrack at i-z dot de
9 years ago
i was wondering whether is_callable or function exists is faster when checking class methods.

is_callable(array('foo', 'bar'));
function_exists('foo::bar');

my results when doing each operation 10000 times with a simple test class were the following:

is_callable: 0.28671383857727 seconds
function_exists: 0.14569997787476 seconds

(following tests have proved this to be true).

thus you can see, function_exists is twice as fast as is_callable.
up
down
0
breadman
10 years ago
Functions within a function are better off as anonymous returns from create_function(), unless you want to be able to call it elsewhere.

However, I have used this in skinning:  I use alert_box() to display certain errors, like a faulty SQL query.  This simply calls display_alert(), which is defined in my skin scripts.  However, alert_box() is sometimes called before I know which skin to load, so it has its own functionality which it uses if function_exists('display_alert') returns false.
up
down
0
dshearin at excite dot com
10 years ago
This can be used to conditionally define a user function. In this sense, it can act as a sort of inline include_once().

For example, suppose you have a function A that calls function B. B is only used inside function A and is never called from anywhere else in the script. It's logical (and perfectly legal in PHP) to define B inside of A's definition, like so:

<?php
function A($inputArray)
{
   if (!
function_exists('B'))
   {
      function
B($item)
      {
          
// Do something with $item
         // and return result
         
return $result;
      }
   }
   foreach (
$inputArray as $nextItem) $outputArray[] = B($nextItem);
   return
$outputArray;   
}
?>

Without the function_exists test, you would get a fatal error the second time you called A, as PHP would think you were trying to redefine B (not legal in PHP). The placement of the test is also important. Since the if block is executed sequentially, like any other block of code, it must come before any call to the function defined within.
up
down
-1
tinelbarb at yahoo dot com
3 years ago
I had a problem with VARIANT set of functions, which are not implemented in some custom compilations of php (like LAMP), so I had to define my own "VARIANT" functions.
Like the users in this page have noticed ( eddiec, for example ), the code
<?php
if ( !function_exists('SOME_FUNCTION')) {
    function
SOME_FUNCTION () {
       
//my run
   
}
}
?>
will not work, since the PHP first parse the script for defined functions/classes (the IF statement will not stop it to find the declaration) and then it runs the script.

So, I noticed the good observation of [neelam_ab2003] and the solution is to create a test function which include the declaration of the custom function. And that's working!
Here is an example for "variant_xor" PHP function:
<?php
function DEFINE_variant_xor () {
    function
variant_xor($a=0, $b=0) {
        return ( (
$a!=$b) && ($a||$b) ) ? TRUE : FALSE ;
    }
}

if ( !
function_exists(' variant_xor')) {
   
DEFINE_variant_xor () ;
   
//which will pass back to the script the declaration of my function
}
?>

Of course, when clone PHP functions, always make sure that your functions works entirely like the original ones with the type of arguments you need :-)
up
down
-1
jeremiah at jkjonesco dot com
5 years ago
If you are trying to use this for testing a "function" within a class, then you need to use method_exists().  A "function" within an object is a method, not a function.
add a note add a note

 
show source | credits | sitemap | contact | advertising | mirror sites