PHP Libxml

libxml error collection, options and version info.

Intermediate
Key PointsBy default XML warnings print to the page — collect them with `libxml_use_internal_errors`.

Functions

FunctionPurpose
libxml_use_internal_errors开启/关闭内部错误收集
libxml_get_errors取错误列表
libxml_get_last_error取最后一个错误
libxml_clear_errors清空错误缓冲
libxml_set_streams_context设置流上下文(超时、代理)
libxml_disable_entity_loader禁用外部实体(8.0 起弃用)

Collecting errors

PHP
<?php
libxml_use_internal_errors(true);

$bad = "<root><a>1</b></root>";

$doc = new DOMDocument();
$ok  = $doc->loadXML($bad);

if (!$ok) {
    foreach (libxml_get_errors() as $e) {
        printf("级别 %d 第 %d 行: %s", $e->level, $e->line, trim($e->message) . "\n");
    }
    libxml_clear_errors();
}

echo $ok ? "解析成功" : "解析失败", "\n";
Output
级别 2 第 1 行: Opening and ending tag mismatch: a line 1 and root
解析失败

$e->level is 1 warning, 2 error, 3 fatal. line and column locate the issue; message describes it.

Forgetting libxml_clear_errors() lets errors accumulate across parses in one request — the next parse reports stale ones.

Options

PHP
<?php
$opts = LIBXML_NONET | LIBXML_NOBLANKS | LIBXML_NOCDATA;

$doc = new DOMDocument();
$doc->loadXML('<r><a>1</a>  <b><![CDATA[x]]></b></r>', $opts);

echo $doc->getElementsByTagName("b")->item(0)->nodeValue, "\n";

// 关闭空白保留后,元素之间的空白文本节点被去掉
echo $doc->documentElement->childNodes->length, "\n";
Output
x
2
OptionEffect
LIBXML_NONET禁止网络加载(防 XXE)
LIBXML_NOBLANKS去掉无意义空白节点
LIBXML_NOCDATACDATA 合并为文本
LIBXML_NOENT展开实体(危险)
LIBXML_DTDLOAD加载外部 DTD(危险)
LIBXML_NOENT and LIBXML_DTDLOAD are the entry points for XXE. Never use them unless you fully understand the risk.

Timeouts and context

PHP
<?php
$ctx = stream_context_create([
    "http" => [
        "timeout" => 5,
        "header"  => "User-Agent: MyApp/1.0\r\n",
    ],
]);

libxml_set_streams_context($ctx);

$doc = new DOMDocument();
$ok  = @$doc->load("https://example.com/feed.xml");

echo $ok ? "加载成功" : "加载失败(超时或不可达)", "\n";
Output
加载成功

DOMDocument::load has no default timeout on remote URLs and will hang. **Set timeout via a stream context** or one slow site blocks a worker.

Version info

PHP
<?php
echo LIBXML_DOTTED_VERSION, "\n";
echo extension_loaded("libxml") ? "libxml 已加载" : "未加载", "\n";
echo function_exists("libxml_use_internal_errors") ? "函数可用" : "函数缺失", "\n";
Output
2.9.14
libxml 已加载
函数可用

Friends & Partners