2009-07-19 13 views
63

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

कोड:

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

यह:

@$xmlDoc->loadHTML($fetchResult) 

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

+0

इस समाधान का प्रयास करें - बहुत आसान हो रहा है - http://stackoverflow.com/questions/6090667/php-domdocument-errors-warnings-on-html5-tags – Marcin

+0

उचित उत्पादन के लिए घटिया इनपुट परिवर्तित क्या है बिल चुकाता है;) [पुनर्प्राप्ति विकल्प मैनुअल में है] (http://nl1.php.net/manual/en/class.domdocument.php#domdocument.props.recover)। यह सिर्फ एक बुलियन है। आप केवल $ $ dom-> saveHTML() 'को कॉल कर सकते हैं, तो देखें कि दस्तावेज़ libxml आपके' $ html' इनपुट को बनाने का प्रयास कर रहा है, तो आमतौर पर यह बहुत करीब/ठीक है। – Wrikken

उत्तर

16

आप के साथ एक अस्थायी त्रुटि हैंडलर स्थापित कर सकते हैं 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()); 
} 
+0

धन्यवाद! इस तरह की एक साफ चाल! कोड सरल और साफ है। – Viet

+7

स्थिति के लिए बहुत अधिक ओवरकिल की तरह लगता है। नोट PHP के libxml2 कार्यों। – thomasrutter

+0

अच्छा बिंदु, थॉमस। जब मैंने यह जवाब लिखा था तो मुझे इन कार्यों के बारे में पता नहीं था। अगर मुझे गलत नहीं लगता है, तो यह वही काम करता है जो आंतरिक रूप से बीटीडब्ल्यू करता है। – troelskn

184

साथ $xmlDoc->loadHTML()

साथ कॉल प्रसंस्करण के लिए

libxml_use_internal_errors(true); 

पहले

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

+17

@ वियत- यह * संभवतः स्वीकार्य उत्तर होना चाहिए ... – Ben

75

चेतावनी छिपाने के लिए, जो आंतरिक रूप से प्रयोग किया जाता है पार्स प्रदर्शन करने के लिए 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); 
+1

क्या मुझे libxml_use_internal_errors (false) का उपयोग करना चाहिए; जब हो जाए? – Greeso

+2

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

+0

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