Manipulador de erros libxml com OOP

Eu preciso de erros catch libxml. Mas eu quero usar minha class para isso. Eu sei sobre libxml_get_errors e outras funções. Mas eu preciso de algo como libxml_set_erroc_class("myclass") e, em todos os casos, o erro irá chamar minha class. Eu não quero em cada caso depois de usar $dom->load(...) criar alguma construção como foreach(libxml_get_errors as $error) {....} . Pode me ajudar?

libxml errors são gerados principalmente ao ler ou escrever o documento xml porque a validação automática é feita.

Então, é aqui que você deveria se concentrar e não precisa replace o set_error_handler . Aqui está uma prova do conceito

Usar erros internos

 libxml_use_internal_errors ( true ); 

XML de exemplo

 $xmlstr = < << XML    PHP: Behind the Parser   XML; echo "
" ;

Eu acho que este é um exemplo do tipo do que você deseja alcançar

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

Classe XMLLoader

 class XmlLoader { private $xml; private $doc; function __construct($xmlstr) { $doc = simplexml_load_string ( $xmlstr ); if (! $doc) { throw new XmlException ( libxml_get_errors () ); } } } 

Classe 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"; } } } 

Saída de amostra

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

Eu espero que isso ajude

obrigado

Não há facilidade para fazer isso diretamente. Suas opções seriam:

  1. estenda a class PHP que usa libxml e envolva sua lógica de gerenciamento de erros personalizada em torno da implementação de estoque (não tão boa), ou
  2. escreva sua própria class que agrega uma instância daquela class PHP e crie sua própria interface pública em torno dela (melhor, porque você está no controle da interface pública e não arrisca problemas se a class PHP for estendida no futuro), ou
  3. substitua o manipulador global de erros durante a duração da análise e restaure-o depois (não tão poderoso, pode ser problemático se o seu código invocar outro código, por mais fácil de fazer)

As soluções 1 e 2 têm a vantagem de não modificar o comportamento de qualquer outro código na sua aplicação, não importa o que.

editar (exceções confusas com erros):

  1. Use set_exception_handler para capturar exceções globais.
  2. Tenha seu código lançar essas exceções em casos como $dom->load() . Como a libxml não parece lançar exceções por conta própria, sua outra opção é criar um wrapper em torno dele, usar o wrapper em seu código e libxml lo verificar libxml para erros e jogá-los nos casos necessários.
  3. Gerencie as exceções dentro de “myclass”.

Desconfie ainda que o set_exception_handler todas as suas exceções.

Aqui está um exemplo do que você poderia fazer:

 //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 }