method_exists仅检查方法是否在类定义中存在,不验证可调用性;传对象查该类及父类,传类名直接查类定义;PHP 7.4+对继承的private方法返回false;会触发autoloader;不可替代is_callable。

method_exists 用来判断方法是否存在,但不保证能调用
它只检查类定义里有没有这个方法名,不管访问控制(private、protected)、静态/非静态、是否被 __call 动态代理。返回 true 只代表“写在类里了”,不代表你当前上下文能安全调用。
传对象和传类名两种用法要分清
第一个参数支持对象实例或类名字符串,行为略有差异:
- 传对象(如
$obj):检查该对象所属类及其父类中是否定义了该方法 - 传类名(如
'MyClass'):直接查类定义,不依赖实例,也适用于未实例化的类 - PHP 7.4+ 对继承的
private方法改了逻辑:即使子类继承了父类的private方法,method_exists($obj, 'xxx')也返回false - 如果类尚未加载,
method_exists会触发已注册的 autoloader —— 这可能带来意外开销或失败
常见误用:拿它代替 is_callable 做调用前校验
这是最典型的坑。比如:
if (method_exists($obj, 'doSomething')) {
$obj->doSomething(); // 如果是 private 方法,这里直接 fatal error
}
正确做法是用 is_callable:
立即学习“PHP免费学习笔记(深入)”;
-
is_callable([$obj, 'doSomething'])会检查可见性、作用域、是否被__call支持 -
method_exists更适合插件系统、反射分析、文档生成等“结构检查”场景 - 两者不是替代关系,而是分工:一个问“有没有写”,一个问“能不能用”
和 function_exists、property_exists 的关键区别
别混淆三者用途:
-
function_exists('foo'):只查全局函数,不查类方法 -
method_exists($obj, 'foo'):只查类方法,不查函数,也不管属性 -
property_exists($obj, 'bar'):只查属性是否存在(哪怕值为null),对__get无效 - 它们都不处理魔术方法的动态行为(
__call、__get等)—— 这类逻辑必须靠运行时试探或自定义规则
method_exists。



















