function_exists() 是检查函数是否存在的最直接安全方式,只查当前符号表,需传字符串、区分大小写、不支持命名空间别名和类方法,且不触发自动加载。

用 function_exists() 检查函数是否已定义
PHP 里判断一个函数是否存在,最直接、最安全的方式就是用 function_exists()。它不关心函数是内置的、用户自定义的,还是通过扩展加载的,只看当前运行时符号表里有没有这个函数名。
常见错误现象:直接调用未声明的函数导致 Fatal error: Uncaught Error: Call to undefined function;或者在条件逻辑里硬写 if (some_func()) 而没兜底,结果一报错就中断。
- 必须传字符串字面量或变量,不能带括号:
function_exists('json_encode')✅,function_exists(json_encode())❌ - 对大小写敏感:
function_exists('StrToLower')返回false,即使strtolower存在 - 不识别命名空间别名,要写完整限定名:
function_exists('My\Helper\format_date'),而不是function_exists('format_date') - 无法检测类方法,那是
method_exists()的事
检查扩展函数前先确认扩展是否启用
很多函数(比如 mb_strlen、curl_init)依赖扩展。光用 function_exists() 不够,因为函数不存在可能是扩展根本没开,不是代码漏写了。
使用场景:写可移植的工具类,或在 Docker / 不同环境部署时做兼容性预检。
立即学习“PHP免费学习笔记(深入)”;
- 先用
extension_loaded('mbstring')或extension_loaded('curl')判断扩展状态 - 再用
function_exists()确认具体函数——有些扩展开启后仍可能因配置禁用个别函数(如disable_functionsini 设置) -
php -m命令行可快速查看已启用扩展,但运行时必须靠代码判断
function_exists() 的性能和边界情况
这个函数本身开销极小,PHP 内部只是查哈希表,不用反射也不加载文件。但要注意它查的是“当前作用域可见”的函数——如果函数在 include 或 require 的文件里,且该文件还没执行到,那 function_exists() 就会返回 false。
- 不会触发自动加载(
__autoload或spl_autoload_register),所以不能靠它“试探”尚未引入的函数文件 - 匿名函数、闭包(
function () {})没有函数名,无法用此函数检测 - PHP 8.0+ 中,JIT 编译不影响其行为,结果始终可靠
替代方案:用 is_callable() 判断“能否调用”
有时候你真正关心的不是“函数存不存在”,而是“现在能不能安全调用它”。比如函数存在,但被 disable_functions 屏蔽了,或是个静态方法但没给对象实例。
is_callable() 更贴近实际执行逻辑,但它比 function_exists() 稍慢,因为要做更多上下文检查。
-
is_callable('json_encode')和function_exists('json_encode')在绝大多数情况下结果一致 - 但
is_callable(['MyClass', 'myMethod'])可以检测类方法是否可访问(包括 private/protected,取决于调用位置) - 如果函数存在但被
disable_functions拦截,is_callable()返回false,而function_exists()仍返回true
function_exists() 就够;涉及类、方法、或需要绕过 disable_functions 的真实可用性判断,才上 is_callable()。别为了“看起来更全”而默认用后者——多出来的检查在高频调用路径里真有感知。











