PHP报错:set_error_handler回调函数未找到或名称无效求助
问题背景
当前架构包含Database类与Utils类,脚本通过初始化Utils类来初始化DatabaseConnection实例(此前直接初始化时功能正常,推测问题与此变更相关)。
为处理DatabaseConnection类中插入操作违反UNIQUE约束的情况(原操作仅抛出无规范响应码的异常警告),编写了私有错误处理方法:
private function postgresFatalWarningErrorHandler($e, $eStr): void{ throw new Exception(explode("DETAIL:", $eStr)[1]); }
在执行可能违反约束的查询时,尝试注册该处理器却触发致命错误:
PHP Fatal error: Uncaught TypeError: set_error_handler(): Argument #1 ($callback) must be a valid callback or null, function "postgresFatalWarningErrorHandler" not found or invalid function name in [path]\dbConnection.php:78
错误原因
PHP的set_error_handler接收字符串形式的函数名时,只会在全局命名空间中查找函数。而postgresFatalWarningErrorHandler是DatabaseConnection类的私有方法,无法通过全局函数名的方式被识别;同时类方法作为回调需要特定的数组格式来指定实例与方法,原代码的字符串写法不符合要求。
解决方法
1. 修正回调传递格式
在类内部注册错误处理器时,类方法的回调必须使用数组形式,包含当前对象实例和方法名,替换原有的字符串写法:
set_error_handler([$this, 'postgresFatalWarningErrorHandler']); $res = pg_execute($this->dbConnection, "query", $dataArray); restore_error_handler();
因为是在类内部调用,所以可以正常访问私有方法,PHP能正确识别这是当前实例的方法。
2. 优化错误处理逻辑(可选)
为了让错误处理更健壮,可以调整方法参数适配PHP错误处理器的标准签名,并增加非目标错误的处理逻辑:
private function postgresFatalWarningErrorHandler(int $errno, string $errstr): void { // 仅处理包含PostgreSQL约束详情的错误 if (str_contains($errstr, 'DETAIL:')) { $detail = trim(explode("DETAIL:", $errstr)[1]); throw new Exception($detail); } // 其他错误交给默认处理器处理 restore_error_handler(); trigger_error($errstr, $errno); }
内容的提问来源于stack exchange,提问作者jqlifice

