与OOP的libxml错误处理程序(libxml error handler with OOP)

2019-09-16 09:17发布

我需要赶上的libxml错误。 但我想用我的类此。 我知道libxml_get_errors等功能。 但是,我需要这样的东西libxml_set_erroc_class("myclass")并在所有的情况下,错误会打电话给我的班。 我不想在使用后每种情况下$dom->load(...)创建一些像建设foreach(libxml_get_errors as $error) {....} 你能帮助我吗?

Answer 1:

libxml errors读取或写入时,大多产生xml文档,因为自动验证完成。

因此,这是你要集中精力,你并不需要覆盖set_error_handler 。这里是一个证明概念

使用内部错误

libxml_use_internal_errors ( true );

示例XML

$xmlstr = <<< XML
<?xml version='1.0' standalone='yes'?>
<movies>
 <movie>
  <titles>PHP: Behind the Parser</title>
 </movie>
</movies>
XML;

echo "<pre>" ;

我想这是那种你想实现什么的例子

try {
    $loader = new XmlLoader ( $xmlstr );
} catch ( XmlException $e ) {
    echo $e->getMessage();
}

XMLLoader类

class XmlLoader {
    private $xml;
    private $doc;
    function __construct($xmlstr) {
        $doc = simplexml_load_string ( $xmlstr );

        if (! $doc) {
            throw new XmlException ( libxml_get_errors () );
        }
    }
}

XmlException类

class XmlException extends Exception {

    private $errorMessage = "";
    function __construct(Array $errors) {

        $x = 0;
        foreach ( $errors as $error ) {
            if ($error instanceof LibXMLError) {
                $this->parseError ( $error );
                $x ++;
            }
        }
        if ($x > 0) {
            parent::__construct ( $this->errorMessage );
        } else {
            parent::__construct ( "Unknown Error XmlException" );
        }
    }

    function parseError(LibXMLError $error) {
        switch ($error->level) {
            case LIBXML_ERR_WARNING :
                $this->errorMessage .= "Warning $error->code: ";
                break;
            case LIBXML_ERR_ERROR :
                $this->errorMessage .= "Error $error->code: ";
                break;
            case LIBXML_ERR_FATAL :
                $this->errorMessage .= "Fatal Error $error->code: ";
                break;
        }

        $this->errorMessage .= trim ( $error->message ) . "\n  Line: $error->line" . "\n  Column: $error->column";

        if ($error->file) {
            $this->errorMessage .= "\n  File: $error->file";
        }
    }

}

样本输出

Fatal Error 76: Opening and ending tag mismatch: titles line 4 and title
  Line: 4
  Column: 46

我希望这有帮助

谢谢



Answer 2:

没有工厂,直接做到这一点。 您的选择将是:

  1. 延长使用libxml的PHP类和包装您的自定义错误处理逻辑周边股市实现(不太好),或
  2. 写自己的类,它聚合了PHP类的一个实例,并围绕它建立自己的公共接口(好,因为你是在公共接口的控制,如果PHP类是在未来扩展你不冒险的问题),要么
  3. 更换全局错误处理程序为您解析的持续时间和事后恢复它(不强大,可能是有问题的,如果你的代码调用到其他代码,然而更容易做到)

方案1和2,他们不修改任何其他代码的行为在你的应用程序无论什么优势。



Answer 3:

编辑 (有错误混淆例外):

  1. 使用set_exception_handler赶上全球例外。
  2. 让你的代码扔在情况下,这些例外像$dom->load() 由于libxml似乎并没有抛出其自己的异常,您的另一种选择是创建一个包装周围,在代码中使用的包装,让它检查libxml错误,并在必要的情况下把他们。
  3. 处理“MyClass的”内部例外。

警惕尽管该set_exception_handler将捕获所有你的异常。

以下是你可以做一个例子:

//inheritance example (composition, though, would be better)
class MyDOMWrapper extends DOMDocument{
    public function load($filename, $options = 0){
        $bool = parent::load($filename, $options);
        if (!$bool){
            throw new MyDOMException('Shit happens. Feeling lucky.', 777);
        }
    }
}
class MyDOMException extends DOMException{
    public $libxml;

    public function __construct($message, $code){
        parent::__construct($message, $code);
        $this->libxml = libxml_get_errors();
    }
}
class MyDOMExceptionHandler{
    public static function handle($e){
        //handle exception globally
    }
}
libxml_use_internal_errors(true);
set_exception_handler(array('MyDOMErrorHandler', 'handle'));

//global exception handler
$myDom = new MyDOMWrapper();
$myDom->load('main.xml');

//when special handling is necessary
try {
    $myDom = new MyDOMWrapper();
    $myDom->load('main.xml');
} catch (MyDOMException $e) {   
    //handle or
    throw $e; //rethrow
}


文章来源: libxml error handler with OOP