DOMDocument (PHP) द्वारा गैर-सुव्यवस्थित HTML लोड करते समय चेतावनी को अक्षम करें


79

मुझे कुछ HTML फ़ाइलों को पार्स करने की आवश्यकता है, हालांकि, वे अच्छी तरह से गठित नहीं हैं और PHP चेतावनी को प्रिंट करता है। मैं इस तरह के डिबगिंग / चेतावनी व्यवहार से प्रोग्राम से बचना चाहता हूं। कृपया सलाह दें। धन्यवाद!

कोड:

// create a DOM document and load the HTML data
$xmlDoc = new DomDocument;
// this dumps out the warnings
$xmlDoc->loadHTML($fetchResult);

यह:

@$xmlDoc->loadHTML($fetchResult)

चेतावनी को दबा सकते हैं, लेकिन मैं उन चेतावनियों को प्रोग्रामेटिक रूप से कैसे पकड़ सकता हूं?


इस समाधान का प्रयास करें - बहुत आसान लगता है - stackoverflow.com/questions/6090667/…
मार्सिन

घटिया इनपुट के लिए घटिया इनपुट परिवर्तित करना बिलों का भुगतान करता है;) वसूली का विकल्प मैनुअल में है । यह सिर्फ एक बूलियन है। आप बस कॉल कर सकते हैं $dom->saveHTML()तो देखें कि यदि दस्तावेज़ libxml आपके $htmlइनपुट को बनाने की कोशिश कर रहा है , तो आमतौर पर यह बहुत करीब / ठीक है।
22

जवाबों:


13

आप के साथ एक अस्थायी त्रुटि हैंडलर स्थापित कर सकते हैं set_error_handler

class ErrorTrap {
  protected $callback;
  protected $errors = array();
  function __construct($callback) {
    $this->callback = $callback;
  }
  function call() {
    $result = null;
    set_error_handler(array($this, 'onError'));
    try {
      $result = call_user_func_array($this->callback, func_get_args());
    } catch (Exception $ex) {
      restore_error_handler();        
      throw $ex;
    }
    restore_error_handler();
    return $result;
  }
  function onError($errno, $errstr, $errfile, $errline) {
    $this->errors[] = array($errno, $errstr, $errfile, $errline);
  }
  function ok() {
    return count($this->errors) === 0;
  }
  function errors() {
    return $this->errors;
  }
}

उपयोग:

// create a DOM document and load the HTML data
$xmlDoc = new DomDocument();
$caller = new ErrorTrap(array($xmlDoc, 'loadHTML'));
// this doesn't dump out any warnings
$caller->call($fetchResult);
if (!$caller->ok()) {
  var_dump($caller->errors());
}

10
स्थिति के लिए बहुत अधिक ओवरकिल की तरह लगता है। नोट PHP के libxml2 फ़ंक्शंस।
थोमसट्रेटर

अच्छी बात है, थॉमस। जब मैंने यह उत्तर लिखा था तब मुझे इन कार्यों के बारे में पता नहीं था। अगर मैं गलत नहीं हूँ, यह आंतरिक रूप से btw एक ही बात करता है।
troelskn

1
इस मामले में इसका एक ही प्रभाव है हाँ, हालांकि यह एक अलग स्तर पर किया गया है: उपरोक्त समाधान के साथ, PHP त्रुटियां उत्पन्न होती हैं लेकिन दबा दी जाती हैं, लेकिन मेरे साथ, वे PHP त्रुटियाँ नहीं बनती हैं। मुझे व्यक्तिगत रूप से लगता है कि यदि कुछ करने से PHP त्रुटियों को @ या set_error_handler () के माध्यम से दबाने में शामिल है, तो यह गलत तरीका है। हालांकि यह सिर्फ मेरी राय है। ध्यान दें कि PHP त्रुटियां और अपवाद पूरी तरह से एक अलग चीज हैं - कोशिश {} कैच () {} का उपयोग करना ठीक है।
थोमसट्रेटर

2
मुझे लगता है कि मैंने कुछ बग रिपोर्ट देखी हैं, जो सुझाव देती हैं कि libxml_use_internal_errorsहुक ने php की त्रुटि हैंडलर को दी।
ट्रॉयल्सकैन

मुझे उम्मीद है कि लोग इस उत्तर को नीचे दिए गए बेहतर उत्तरों के साथ स्क्रॉल करेंगे।
थोमसट्रेटर

222

कॉल

libxml_use_internal_errors(true);

के साथ प्रसंस्करण से पहले $xmlDoc->loadHTML()

यह libxml2 को PHP के माध्यम से त्रुटियों और चेतावनियों को नहीं भेजने के लिए कहता है । फिर, त्रुटियों की जांच करने और उन्हें स्वयं को संभालने के लिए, आप तैयार होने पर libxml_get_last_error () और / या libxml_get_errors () से परामर्श कर सकते हैं।


1
इतना आसान है कि स्वीकृत उत्तर के अनुसार कोड की 20 पंक्तियों को जोड़ना है। धन्यवाद!
ब्रायन क्लुग

94

चेतावनियाँ छिपाने के लिए, आपको विशेष निर्देश देने होते हैं libxmlजिसका उपयोग आंतरिक रूप से पार्सिंग करने के लिए किया जाता है:

libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();

libxml_use_internal_errors(true)इंगित करता है कि आप त्रुटियों और चेतावनियों खुद को संभालने के लिए जा रहे हैं और आप अपना स्क्रिप्ट का आउटपुट ऊपर गड़बड़ करने के लिए उन्हें चाहते हैं।

यह @ऑपरेटर के समान नहीं है । चेतावनियाँ पर्दे के पीछे एकत्रित हो जाती हैं और बाद में जब आप libxml_get_errors()लॉगिंग करने या कॉल करने के लिए मुद्दों की सूची वापस करना चाहते हैं, तो आप उन्हें पुनः प्राप्त कर सकते हैं ।

आप एकत्रित चेतावनियों का उपयोग कर रहे हैं या नहीं, आपको हमेशा कॉल करके कतार साफ़ करनी चाहिए libxml_clear_errors()

राज्य का संरक्षण

यदि आपके पास अन्य कोड है जो libxmlइसका उपयोग करता है, तो यह सुनिश्चित करना सार्थक हो सकता है कि आपका कोड त्रुटि से निपटने की वैश्विक स्थिति में परिवर्तन नहीं करता है ; इसके लिए, आप libxml_use_internal_errors()पिछली स्थिति को बचाने के लिए रिटर्न मान का उपयोग कर सकते हैं ।

// modify state
$libxml_previous_state = libxml_use_internal_errors(true);
// parse
$dom->loadHTML($html);
// handle errors
libxml_clear_errors();
// restore
libxml_use_internal_errors($libxml_previous_state);

2
@Greeso: यह पिछले मान पर सेट है । यह इस अवधारणा द्वारा किया जाता है कि इसे विश्व स्तर पर कुछ अन्य कोड के लिए कॉन्फ़िगर किया गया है FALSEऔर FALSEबाद में इसे स्थापित करने से यह सेटिंग नष्ट हो जाएगी। पिछले रिटर्न मूल्य का उपयोग करके $libxml_previous_stateउन संभावित दुष्प्रभावों को रोका जाता है क्योंकि मूल कॉन्फ़िगरेशन को इस स्थान की जरूरतों के लिए स्वतंत्र रूप से बहाल किया गया है। libxml_use_internal_errors()की स्थापना, वैश्विक है, इसलिए यह कुछ देखभाल करने के लिए लायक है।
हक्रे

यदि पहले से ही libxml त्रुटियाँ लंबित हैं, तो क्या यह उन्हें नहीं खाएगा?
cHao

@ CHao यह मान लेना उचित नहीं है कि आप एक खाली स्लेट के साथ शुरू कर रहे हैं? :)
Ja .ck

@ Ja @ck: नहींं। यदि पहले से कुछ कहा जाता है libxml_use_internal_errors(true), तो जो भी त्रुटियां उत्पन्न हुई हैं, उसे संभालने के लिए इंतजार करना पड़ सकता है।
cHao

23

"LIBXML_NOWARNING" और "LIBXML_NOERROR" विकल्प सेट करना पूरी तरह से ठीक काम करता है:

$dom->loadHTML($html, LIBXML_NOWARNING | LIBXML_NOERROR);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.