libxml error handler with OOP
error-handling, libxml2, oop, php
Solution
`libxml errors` are mostly generated when reading or writing `xml` document because automatic validation is done.
So this is where you should concentrate and you don't need to overwrite the `set_error_handler` .. Here is a prove of concept
Use Internal Errors
libxml_use_internal_errors ( true );
Sample XML
$xmlstr = <<< XML
<?xml version='1.0' standalone='yes'?>
<movies>
<movie>
<titles>PHP: Behind the Parser</title>
</movie>
</movies>
XML;
echo "<pre>" ;
I guess this is an example of the kind of what you want to achieve
try {
$loader = new XmlLoader ( $xmlstr );
} catch ( XmlException $e ) {
echo $e->getMessage();
}
XMLLoader Class
class XmlLoader {
private $xml;
private $doc;
function __construct($xmlstr) {
$doc = simplexml_load_string ( $xmlstr );
if (! $doc) {
throw new XmlException ( libxml_get_errors () );
}
}
}
XmlException Class
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";
}
}
}
Sample Output
Fatal Error 76: Opening and ending tag mismatch: titles line 4 and title
Line: 4
Column: 46
I hope this helps
Thanks
Problem
I need catch libxml errors. But I want to use my class for this. I know about `libxml_get_errors` and other function. But I need something like `libxml_set_erroc_class("myclass")` and in all case for error will call my class. I don't want in each case after use `$dom->load(...)` create some construction like `foreach(libxml_get_errors as $error) {....}`. Can you help me?