Xml parser free: примеры (PHP)

Руководство по применению xml_parser_free в PHP
Раздел: XML
xml_parser_free(resource parser): bool

Функция xml_parser_free

Описание и назначение

Функция xml_parser_free освобождает память, занятую XML-парсером, созданным функцией xml_parser_create() или xml_parser_create_ns(). После вызова этой функции парсер становится недействительным, и дальнейшая работа с ним невозможна.

Когда используется

Функцию вызывают после завершения разбора XML-документа или при необходимости принудительно освободить ресурсы парсера, например, в случае ошибки. Использование этой функции особенно важно в длительных скриптах для предотвращения утечек памяти.

Аргументы функции

Функция принимает один обязательный параметр:

  • parser (ресурс) — ссылка на XML-парсер, который требуется освободить.

Функция возвращает логическое значение: true в случае успеха и false, если параметр parser не ссылается на корректный парсер.

Краткие примеры использования

Освобождение парсера после успешного разбора

Пример показывает базовый сценарий использования.

<?php
$xml = "<root><item>Тест</item></root>";
$parser = xml_parser_create();

if (xml_parse($parser, $xml, true)) {
    echo "XML разобран успешно.\n";
} else {
    echo "Ошибка разбора XML.\n";
}

// Освобождение парсера
$result = xml_parser_free($parser);
var_dump($result); // bool(true)
?>
XML разобран успешно.
bool(true)
Попытка освободить недействительный парсер
<?php
$parser = xml_parser_create();
xml_parser_free($parser);

// Повторная попытка освободить тот же парсер
$result = xml_parser_free($parser);
var_dump($result); // bool(false)
?>
bool(false)

Похожие функции в PHP

xml_parser_create и xml_parser_create_ns

Функции создают XML-парсер. xml_parser_create_ns() дополнительно поддерживает пространства имен. Они не являются прямыми альтернативами освобождению, но всегда используются в паре с xml_parser_free().

Автоматическое освобождение

Ресурс парсера автоматически освобождается по завершении работы скрипта. Однако в долго работающих приложениях, например, серверных демонах, явный вызов xml_parser_free() необходим для управления памятью.

Расширение SimpleXML и DOMDocument

Для работы с XML в PHP чаще используют объектно-ориентированные расширения SimpleXML и DOMDocument. Они управляют памятью автоматически через сборщик мусора, поэтому не требуют явного освобождения ресурсов.

Альтернативы в других языках

Python: xml.parsers.expat

В модуле xml.parsers.expat парсер создается как объект. Память освобождается автоматически при удалении объекта или завершении работы интерпретатора.

import xml.parsers.expat

parser = xml.parsers.expat.ParserCreate()
# ... разбор XML
# Явного метода освобождения нет, память управляется сборщиком мусора
del parser  # Опционально
JavaScript (Node.js): sax

В пакете sax для Node.js парсер также является объектом. Ресурсы освобождаются при удалении объекта.

const sax = require('sax');
const parser = sax.parser(true);
// ... настройка обработчиков и разбор
parser.end(); // Завершение разбора
// Дальнейшее освобождение — задача сборщика мусора

Xml parser free в MySQL

MySQL не имеет прямых аналогов, так как не предназначен для синтаксического разбора XML в памяти процедурным способом. Для извлечения данных из XML-строк используются функции типа ExtractValue().

Типичные ошибки

Освобождение парсера до завершения разбора

Если освободить парсер до передачи всех данных или до окончания разбора, это вызовет ошибку при последующих попытках использовать парсер.

<?php
$parser = xml_parser_create();
xml_parser_free($parser);

$xmlChunk = "<root>";
// Попытка использовать освобожденный парсер
if (!xml_parse($parser, $xmlChunk, false)) {
    echo "Ошибка: ", xml_error_string(xml_get_error_code($parser));
}
?>
Ошибка: no element found
Передача некорректного ресурса

Передача значения, которое не является ресурсом XML-парсера, приводит к возврату false и генерации предупреждения.

<?php
$result = xml_parser_free(null);
var_dump($result);
?>
Warning: xml_parser_free() expects parameter 1 to be resource, null given in ...
bool(false)

Изменения в последних версиях PHP

В PHP 8.0 тип параметра parser был изменен с ресурса (resource) на объект (XMLParser). Это часть общей тенденции замены ресурсов на объекты. Функция xml_parser_free() теперь принимает и возвращает экземпляр XMLParser.

<?php
// PHP 8.0+
$parser = xml_parser_create();
// $parser теперь объект XMLParser, а не ресурс
$result = xml_parser_free($parser);
var_dump($result);
?>
bool(true)

При передаче неверного типа аргумента в PHP 8 будет выброшена ошибка TypeError, а не предупреждение, как в предыдущих версиях.

Расширенные примеры использования

Освобождение парсера в обработчике ошибок

Пример показывает освобождение парсера при возникновении ошибки разбора.

Пример php
<?php
function parseXMLData($xmlString) {
    $parser = xml_parser_create();
    xml_set_element_handler($parser, "startElement", "endElement");

    if (!xml_parse($parser, $xmlString, true)) {
        $errorCode = xml_get_error_code($parser);
        $errorString = xml_error_string($errorCode);
        $line = xml_get_current_line_number($parser);
        echo "Ошибка разбора XML ($errorString) в строке $line\n";
        xml_parser_free($parser); // Освобождение при ошибке
        return false;
    }

    xml_parser_free($parser); // Освобождение при успехе
    return true;
}

function startElement($parser, $name, $attrs) {}
function endElement($parser, $name) {}

$badXml = "<root><item>Без закрывающего тега";
parseXMLData($badXml);
?>
Ошибка разбора XML (no element found) в строке 1
Работа с несколькими парсерами

В сложных сценариях может использоваться несколько парсеров одновременно. Важно освобождать каждый из них.

Пример php
<?php
$xml1 = "<doc1>Контент 1</doc1>";
$xml2 = "<doc2>Контент 2</doc2>";

$parser1 = xml_parser_create();
$parser2 = xml_parser_create_ns(); // Парсер с поддержкой пространств имен

xml_parse($parser1, $xml1, true);
xml_parse($parser2, $xml2, true);

// Освобождение всех парсеров
xml_parser_free($parser1);
xm l_parser_free($parser2);

echo "Оба парсера освобождены.\n";
?>
Оба парсера освобождены.
Интеграция в класс

Пример инкапсуляции парсера в класс с автоматическим освобождением в деструкторе.

Пример php
<?php
class XmlStreamParser {
    private $parser;

    public function __construct() {
        $this->parser = xml_parser_create();
    }

    public function parse($data, $isFinal = false) {
        return xml_parse($this->parser, $data, $isFinal);
    }

    public function __destruct() {
        if ($this->parser) {
            xml_parser_free($this->parser);
            $this->parser = null;
        }
    }
}

$parserObj = new XmlStreamParser();
$parserObj->parse("<root>", false);
$parserObj->parse("data</root>", true);
// При удалении объекта парсер будет автоматически освобожден
unset($parserObj);
?>

PHP xml_parser_free function comments

En
Xml parser free Free an XML parser