PHP Conference Japan 2024

method_exists

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

method_exists检查类方法是否存在

描述

method_exists(对象|字符串 $object_or_class, 字符串 $method): 布尔值

检查给定 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)

注释

注意:

使用此函数将在类尚未知时使用任何已注册的 自动加载器

参见

添加注释

用户贡献的注释 20 条注释

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
?>
El
5 年前
自 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)
jave [at] issomewhereontheweb [com]
8 年前
该函数不关心类是否存在,因此即使未声明类,也可以使用它来检查方法是否存在,例如
<?php
if( method_exists('THIS_WAS_NOT_DECLARED', 'some_method') )
echo
"它确实存在!";
else
echo
"不,它不存在...";
?>
...不引发任何错误/警告...如果类根本不存在或存在但方法不存在,则输出“不,它不存在...” 。
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
benjamin_ansbach at web dot de
21 年前
如果要检查类“内部”的方法,请使用

method_exists($this, 'function_name')

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

method_exists($object_name, 'method_name')

对于那些没有理解我意思的人(可能是由于英语不好造成的 :) )的一个小例子

<?php

a {

函数
a() {

if(
method_exists($this, 'test'))
echo
'a::test() 存在!';
else
echo
'a::test() 不存在';

}


函数
test() {

return
true;

}

}

$b = new a();

?>

输出结果将是:a::test() 存在!

也许这对某些人会有帮助
来自 syneto net 的 florin
15 年前
此函数不区分大小写(PHP 也是如此),以下为证明
<?php
A {
public function
FUNC() { echo '*****'; }
}

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

<?php
ParentClass {

函数
doParent() { }
}

ChildClass extends 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')));
?>
[email protected]
11 年前
请注意,即使调用类在同一命名空间中,也需要加上命名空间(如果有)

<?php
命名空间 test;
foo {
public function
lookup() {
// 将返回 false
return method_exists('bar', 'nonsense_method');
}
}

bar {
public function
nonsense_method() {
// 将返回 true
return method_exists('test\foo', 'lookup');
}
}
?>
匿名用户
14 年前
如果要在一个类本身中检查某个方法是否已知,可以使用魔法变量 __CLASS__

<?php

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

private function
foo(){

}
}

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

?>

您也可以使用下面描述的方法结合 <?php in_array() ?> 技巧,但我认为这个更容易阅读,而且,这正是它应该被使用的方式;)
[email protected]
18 年前
请注意,在 PHP5 中,method_exists() 将成功找到 *私有* 方法。这有一些面向对象/数据隐藏的影响。
[email protected]
14 年前
虽然没有明确说明,但可以推断:method_exists() 也适用于接口。

<?php

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

?>
[email protected]
20 年前
一点区别

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

<?php
if (method_exists($myinstance,'themethod'))
echo
'ok';
?>

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

<?php
if (is_callable(array('theclassname','themethod')))
echo
'ok';
?>
[email protected]
15 年前
您好,

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

如下所示

<?php
// 类示例
myClass {

private
$private1;

static
$static1;

public
$public1;


public function
publ() {

}

private function
priv() {

}

private static function
privstatic() {

}

public static function
publstatic() {

}

static function
mytest() {

}
}

// 此函数使用 PHP 中内置的反射类!
// 目的是确定存在的特定方法的类型
function is_class_method($type="public", $method, $class) {
// $type = mb_strtolower($type);
$refl = new ReflectionMethod($class, $method);
switch(
$type) {
case
"static":
return
$refl->isStatic();
break;
case
"public":
return
$refl->isPublic();
break;
case
"private":
return
$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 方法是公有的,也是静态的,而不是私有的
// 你明白了。我希望这能帮助某些人。
?>
[email protected]
10 年前
我想知道是否将方法缓存到数组中会加快查找速度。因此,我使用 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 似乎最快,而使用字符串作为第一个参数是最慢的。

请注意,测试是在多个方法上进行的,而不仅仅是一个,上面提供的代码是为了展示结果,而不是实际运行的测试代码。此外,这只是出于好奇进行的测试,我没有设置特定的环境或使用任何性能分析工具,并且它并不意味着以任何方式成为正式的基准测试。
j dot metzger at steptown dot com
22 年前
call_user_method 使用与普通方法调用相同的机制。因此,您可以通过这种方式获取返回值。

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

所有信息都包含在 $pagetext 中。
jp at function dot fi
18 年前
如前所述,is_callable 和 method_exists 报告所有可调用的方法,即使它们是私有/受保护的,并且实际上不可调用。因此,您可以使用以下解决方法来代替这些函数,该方法按预期报告方法。

<?php
class Foo1 {
public function
bar() {
echo
"I'm private Foo1::bar()";
}
}

class
Foo2 {
private function
bar() {
echo
"I'm public Foo2::bar()";
}
}

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

if(
is_callable(array($f1,"bar"))) {
echo
"Foo1::bar() is callable";
} else {
echo
"Foo1::bar() isn't callable";
}
if(
is_callable(array($f2,"bar"))) {
echo
"Foo2::bar() is callable";
} else {
echo
"Foo2::bar() isn't callable";
}
if(
in_array("bar",get_class_methods($f1))) {
echo
"Foo1::bar() is callable";
} else {
echo
"Foo1::bar() isn't callable";
}
if(
in_array("bar",get_class_methods($f2))) {
echo
"Foo2::bar() is callable";
} else {
echo
"Foo2::bar() isn't callable";
}

?>

输出
Foo1::bar() is callable (正确)
Foo2::bar() is callable (错误)
Foo1::bar() is callable (正确)
Foo2::bar() isn't callable (正确)

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

<?php
class Something
{

/**
* 动态调用方法
*
* @param string $method
* @param array $args
* @return mixed
*/
public function __call($method, $args)
{
if(
method_exists($this, $method)) {
return
call_user_func_array(array($this, $method), $args);
}else{
throw new
Exception(sprintf('The required method "%s" does not exist for %s', $method, get_class($this)));
}
}

}
?>
spam at majiclab dot com
18 年前
method_exists() 和 is_callable() 都返回私有和受保护的函数,如以下所述,这会导致 PHP5/OO 编程出现问题。您可以将 get_class_methods() 与类的 $instance 或 'ClassName' 一起使用,以仅获取公共函数。
Thomas@ThBeckmann
21 年前
但是,正如 Bejamin 所指出的,在类定义中无法在 method_exists 中使用类名,即使在类内部,get_class_methods 也会为给定的类名提供方法名。因此,上述问题的另一种解决方法是使用 in_array(<method_name>, get_class_methods(<class_name>))
@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