PHP token_get_all
函数(允许将PHP源代码转换为标记)可能会抛出两个错误:一个是遇到未终止的多行注释,另一个是遇到意外的char。
我想抓住这些错误并将其作为例外投放。
问题是:由于这些错误是解析错误,因此无法使用您通常使用set_error_handler
指定的错误处理函数来处理它们。
我目前实施的内容如下:
// Reset the error message in error_get_last()
@$errorGetLastResetUndefinedVariable;
$this->tokens = @token_get_all($code);
$error = error_get_last();
if (preg_match(
'~^(Unterminated comment) starting line ([0-9]+)$~',
$error['message'],
$matches
)
) {
throw new ParseErrorException($matches[1], $matches[2]);
}
if (preg_match(
'~^(Unexpected character in input:\s+\'(.)\' \(ASCII=[0-9]+\))~s',
$error['message'],
$matches
)
) {
throw new ParseErrorException($matches[1]);
}
很明显,我对使用该解决方案并不感到兴奋。特别是我通过访问未定义的变量重置error_get_last
中的错误消息这一事实似乎非常不令人满意。
那么:这个问题有更好的解决方案吗?
答案 0 :(得分:-1)
使用set_error_handler
设置自定义错误处理程序。
致电token_get_all
。
然后通过调用restore_error_handler
取消设置错误处理程序。
这将允许您捕获警告。确保删除@
抑制器。
例如,您可以注册一个类中的错误处理程序,该类将仅记录任何警告以供日后检查。
未经测试的示例代码:
class CatchWarnings {
private $warnings = array();
public function handler($errno, $errstr, $errfile, $errline) {
switch ($errno) {
case E_USER_WARNING:
$this->warnings[] = $errstr;
return true; // cancel error handling bubble
}
return false; // error handling as usual
}
public function has_warnings() {
return count($this->warnings) > 0;
}
}
$cw = new CatchWarnings();
set_error_handler(array($cw, "handler"));
token_get_all();
restore_error_handler();
通常验证和执行是两个独立的事情,但似乎没有办法验证/ lint一段PHP代码(不管是从5.x开始)。