method_exists

(PHP 4, PHP 5, PHP 7, PHP 8)

method_exists检查类方法是否存在

说明

method_exists(object|string $object_or_class, string $method): bool

检查给定的 object_or_class 中是否存在类方法。

参数

object_or_class

对象实例或类名

method

方法名称

返回值

如果给定 object_or_class 中定义了由 method 指定的方法,则返回 true,否则返回 false

范例

范例 #1 method_exists() 例子

<?php
$directory
= new Directory('.');
var_dump(method_exists($directory,'read'));
?>

上面的例子将输出

bool(true)

范例 #2 静态 method_exists() 例子

<?php
var_dump
(method_exists('Directory','read'));
?>

上面的例子将输出

bool(true)

注释

注意:

如果类尚未被识别,使用此函数将使用任何注册的 自动加载器

参见

添加注释

用户贡献注释 21 条注释

65
phoenix at todofixthis dot com
13 年前
如 [其他地方] 所述,method_exists() 不关心 __call() 的存在,而 is_callable() 则关心

<?php
class Test {
public function
explicit( ) {
// ...
}

public function
__call( $meth, $args ) {
// ...
}
}

$Tester = new Test();

var_export(method_exists($Tester, 'anything')); // false
var_export(is_callable(array($Tester, 'anything'))); // true
?>
28
El
4 年前
自 7.4.0 发布以来,未记录的更改

<?php
class Foo
{
private function
privateMethodTest()
{

}
}

class
Bar extends Foo
{

}

var_dump(method_exists(Bar::class, 'privateMethodTest'));
// PHP 7.4: bool(false)
// PHP 7.3: bool(true)

var_dump(is_callable(Bar::class, 'privateMethodTest'));
// PHP 7.3: bool(true)
// PHP 7.4: bool(true)
19
jave [at] issomewhereontheweb [com]
8 年前
该函数不关心类是否存在,因此即使类未声明,也可以使用它来检查方法是否存在,例如
<?php
if( method_exists('THIS_WAS_NOT_DECLARED', 'some_method') )
echo
"it does exist!";
else
echo
"nope, it is not there...";
?>
...不引发任何错误/警告...如果类根本不存在,或者如果类存在但方法不存在,则输出“nope, it is not there...”。
21
w3dk
9 年前
一些较旧的评论(特别是“jp at function dot fi”和“spam at majiclab dot com”)指出,is_callable() 在类外部检查时,不会考虑方法的可见性。 也就是说,私有/受保护的方法在公开测试时被视为可调用。 但是,这是早期版本的 PHP 5 中的一个错误(#29210),并在 PHP 5.0.5(或 PHP 5.1.0)中修复(根据变更日志)。

错误#29210 - 函数:is_callable - 不支持私有和受保护类
http://bugs.php.net/29210

变更日志 - 修复了错误#29210(函数:is_callable - 不支持私有和受保护类)。 (Dmitry)
https://php.net/ChangeLog-5.php#5.1.0
21
benjamin_ansbach at web dot de
21 年前
如果您想检查类“内部”的方法,请使用

method_exists($this, 'function_name')

我有点困惑,因为我以为我只能在得到一个对象时检查方法,例如 $object_name = new class_name(),使用

method_exists($object_name, 'method_name')

一个小例子,适合那些没理解我意思的人(可能因为我的英语不好 :))

<?php

class a {

function
a() {

if(
method_exists($this, 'test'))
echo
'a::test() exists!';
else
echo
'a::test() doesn\'t exists';

}


function
test() {

return
true;

}

}

$b = new a();

?>

输出将为:a::test() exists!

也许这对某些人有帮助
17
florin from syneto net
14 年前
此函数不区分大小写(PHP 也一样),以下证明
<?php
class A {
public function
FUNC() { echo '*****'; }
}

$a = new A();
$a->func(); // *****
var_dump(method_exists($a, 'func')); // bool(true)
?>
21
Niels
13 年前
顺便说一句:method_exists() 和 is_callable() 都对继承的方法返回 true

<?php
ParentClass {

函数
doParent() { }
}

ChildClass 扩展 ParentClass { }

$p = new ParentClass();
$c = new ChildClass();

// 所有都返回 true
var_dump(method_exists($p, 'doParent'));
var_dump(method_exists($c, 'doParent'));

var_dump(is_callable(array($p, 'doParent')));
var_dump(is_callable(array($c, 'doParent')));
?>
9
konzertheld 在 thedomainistheusersname 点 de
11 年前
请注意,即使调用类在同一个命名空间中,也需要在命名空间(如果有)前面加上前缀。

<?php
命名空间 test;
foo {
公共函数
lookup() {
// 将返回 false
返回 method_exists('bar', 'nonsense_method');
}
}

bar {
公共函数
nonsense_method() {
// 将返回 true
返回 method_exists('test\foo', 'lookup');
}
}
?>
5
匿名
14 年前
如果您想在类本身中检查某个方法是否已知,您可以使用魔术变量 __CLASS__。

<?php

A{
__construct($method){
返回
method_exists(__CLASS__,$method);
}

私有函数
foo(){

}
}

$test = new A('foo');
// 应该返回 true

?>

您也可以使用下面描述的方法以及 <?php in_array() ?> 技巧,但我认为这里更容易阅读,并且,这是它的本意 ;)
4
daniel 在 softel 点 jp
18 年前
请注意,在 PHP5 中,method_exists() 将成功找到 *私有* 方法。这有一些 OO/数据隐藏的影响。
1
uramihsayibok,gmail,com
14 年前
虽然没有明确说明,但可以推断:method_exists() 也适用于接口。

<?php

var_dump
(method_exists("Iterator", "current"));
// bool(true)

?>
2
jpgiot 在 nospam ifrance 点 com
20 年前
有一点区别

要查找对象(类的实例)的方法

<?php
如果 (method_exists($myinstance,'themethod'))
回显
'ok';
?>

要查找类的(使用类名,而不是类的实例!)方法

<?php
如果 (is_callable(array('theclassname','themethod')))
回显
'ok';
?>
-1
admin ( 在 ) djokodonev 点 com
14 年前
您好,

这是一个有用的函数,您可以使用它来检查类的访问方法,例如它是公共的、私有的、静态的或两者兼有。

就是这样

<?php
// 示例类
myClass {

私有
$private1;

静态
$static1;

公共
$public1;


公共函数
publ() {

}

私有函数
priv() {

}

私有静态函数
privstatic() {

}

公共静态函数
publstatic() {

}

静态函数
mytest() {

}
}

// 该函数使用 PHP 中内置的反射类!!!
// 目的是确定现有特定方法的类型
函数 is_class_method($type="public", $method, $class) {
// $type = mb_strtolower($type);
$refl = new ReflectionMethod($class, $method);
switch(
$type) {
case
"static":
返回
$refl->isStatic();
break;
case
"public":
返回
$refl->isPublic();
break;
case
"private":
返回
$refl->isPrivate();
break;
}
}
var_dump(is_class_method("static", "privstatic", "myClass")); // true - 该方法是私有的也是静态的。
var_dump(is_class_method("private", "privstatic", "myClass")); // true - 该方法是私有的也是静态的。
var_dump(is_class_method("private", "publstatic", "myClass")); // False 该方法是公共的也是静态的,而不是私有的
// 你明白了。我希望这能帮助到某个人。
?>
-2
j 点 metzger 在 steptown 点 com
22 年前
call_user_method 使用与普通方法调用相同的机制。因此,您可以通过这种方式获取返回的值。

$pagetext=call_user_method($method,$object_call);

所有信息都在 $pagetext 中。
-5
jp 在 function 点 fi
18 年前
如前所述,is_callable 和 method_exists 会报告所有可调用的方法,即使它们是私有的/受保护的,因此实际上不可调用。因此,您可以使用以下变通方法,该方法可以报告应有的方法。

<?php
Foo1 {
公共函数
bar() {
回显
"我是私有的 Foo1::bar()";
}
}

Foo2 {
私有函数
bar() {
回显
"我是公共的 Foo2::bar()";
}
}

$f1=new Foo1;
$f2=new Foo2;

如果(
is_callable(array($f1,"bar"))) {
回显
"Foo1::bar() 是可调用的";
} 否则 {
回显
"Foo1::bar() 不是可调用的";
}
如果(
is_callable(array($f2,"bar"))) {
回显
"Foo2::bar() 是可调用的";
} 否则 {
回显
"Foo2::bar() 不是可调用的";
}
如果(
in_array("bar",get_class_methods($f1))) {
回显
"Foo1::bar() 是可调用的";
} 否则 {
回显
"Foo1::bar() 不是可调用的";
}
如果(
in_array("bar",get_class_methods($f2))) {
回显
"Foo2::bar() 是可调用的";
} 否则 {
回显
"Foo2::bar() 不是可调用的";
}

?>

输出
Foo1::bar() 是可调用的(正确)
Foo2::bar() 是可调用的(不正确)
Foo1::bar() 是可调用的(正确)
Foo2::bar() 不是可调用的(正确)

?>
-5
mail 在 bartrail 点 de
13 年前
在对象的 __call() 方法中使用 method_exists 可以非常有用,如果您想避免由于函数嵌套限制而导致的致命错误,或者如果您正在调用不存在但需要在应用程序中继续执行的方法。

<?php
Something
{

/**
* 动态调用方法
*
* @param string $method
* @param array $args
* @return mixed
*/
public function __call($method, $args)
{
如果(
method_exists($this, $method)) {
返回
call_user_func_array(array($this, $method), $args);
} 否则 {
抛出 new
Exception(sprintf('所需的 "%s" 方法对于 %s 不存在', $method, get_class($this)));
}
}

}
?>
-3
spam 在 majiclab 点 com
18 年前
method_exists() 和 is_callable() 函数都会返回私有和受保护的函数,正如下面提到的,这会导致 PHP5/OO 编程出现问题。你可以使用 get_class_methods() 函数,传入一个类的实例 $instance 或类名 'ClassName' 来获取只包含公共函数的数组。
-4
charleston olaes at gmail no spaces
9 年前
我想知道将方法缓存到数组中是否会更快地查找。所以我使用 xdebug_time_index() 函数,对每个语句进行 10000 次迭代,并进行了非常简单的基准测试。

使用 PHP 5.3.13 版。

<?php
// 使用对象的实际实例显示 0.10398316383362 秒
method_exist($object, $method);
?>

<?php
// 使用字符串显示 0.12779307365417 秒
method_exist('ClassName', $method);
?>

<?php
$array
= array(/*方法名,以数字索引*/);
// 显示 0.10288906097412 秒
in_array($method, $array);
?>

<?php
$assoc
= array( /*方法名作为键值对*/ );
// 显示 0.017536878585815 秒
isset( $assoc[$method] );
?>

从结果来看,method_exist 和 in_array 的差别很小。isset 似乎是最快的,而使用字符串作为第一个参数是最慢的。

请注意,测试是在多个方法上进行的,而不仅仅是一个方法,上面展示的代码只是为了显示结果,而不是实际运行的测试代码。此外,这只是出于好奇进行的测试,我没有设置特定的环境或使用任何性能分析工具,它也不是官方基准测试。
-2
Thomas@ThBeckmann
21 年前
不过,正如 Bejamin 指出的,在类定义中不能在 method_exists 中使用类名,get_class_methods 函数即使在类内部也能获取给定类名的所有方法名。因此,解决上述问题的另一种方法是在类中使用 in_array(<method_name>, get_class_methods(<class_name>))。
-7
seufert at gmail dot com
18 年前
请注意,在使用静态成员函数时,此函数的行为在 5.0.x 版和 5.1.x 版之间有所改变。

使用以下代码:
<?php
class a {
static function
test() {return "A";}
}
if(
method_exists('a','test'))
print
call_user_func(array('a','test'));
else
print
"Nothing";
?>
PHP 5.1.x 版返回 "A"
PHP 5.0.x 版返回 "Nothing"

目前还不确定在 PHP 5.0.x 版中如何解决这个问题。
-5
@prhldchauhan
2 年前
如果你想在包含这个类之后,在不同的文件中使用 "method_exit" 函数,那么你不能直接使用 "method_exit"

所以,你需要使用 call_user_func_array 函数来调用类中已有的基本函数。

然后以以下方式调用函数:=>

function check($fun) {

if(method_exists($this, $fun))
{return true;}
else
{return false;}


}
To Top