DOMDocument-> gt; save () завершается ошибкой после обработки user_abort

В PHP, возможно функции отключения регистрации, который (иногда игнорируется) определенно вызывается в моем сценарии, см. ниже.

PHP / libxml поддерживается Класс DOMDocument в PHP не играет хорошо с моим зарегистрированным функции отключения, если я хочу позвонить ->save() (->saveXML() работает нормально) после пользователь прерван (например, из зарегистрированных shutdown function или экземпляр класса destructor). Связанный также Обработка PHP-соединения.

Пусть примеры говорят:

Версия PHP:

php --version
PHP 7.1.4 (cli) (built: Apr 25 2017 09:48:36) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

Воспроизвести user_abort Я запускаю PHP через python2.7 run.py:

import subprocess

cmd = ["/usr/bin/php", "./user_aborted.php"]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)

# As this process exists here and the user_aborted.php
# has sleeps/blocks in for-cycle thus simulating a user-abort
# for the php subprocess.

PHP скрипт user_aborted.php в попробуйте сохранить XML в функции выключения :

<?php

ignore_user_abort(false);
libxml_use_internal_errors(true);

$xml = new DOMDocument();
$xml_track = $xml->createElement( "Track", "Highway Blues" );
$xml->appendChild($xml_track);

function shutdown() {
global $xml;

$out_as_str = $xml->saveXML();

fwrite(STDERR, "\nout_as_str: " . var_export($out_as_str, true) . "\n");

$out_as_file = $xml->save('out.xml');

fwrite(STDERR, "\nout_as_file: >" . var_export($out_as_file, true) . "<\n");
fwrite(STDERR, "\nerrors: \n" . var_export(libxml_get_errors(), true) . "\n");
}

register_shutdown_function('shutdown');

$i = 2;

while ($i > 0) {
fwrite(STDERR, "\n PID: " . getmypid() . " aborted: " . connection_aborted());
echo("\nmaking some output on stdout"); // so user_abort will be checked
sleep(1);
$i--;
}

Теперь, если я запускаю этот скрипт без прерывания пользователя (просто вызывая PHP) с помощью:
php user_aborted.php XML сохраняется правильно.

тем не мение при вызове через python2.7 (который симулирует прерывание пользователя выйдя из родительского процесса), python2.7 run.py происходят самые странные вещи:

  • out_as_str значение в порядке, выглядит XML я хотел
  • НО файл out.xml это пустой файл
  • ТАКЖЕ libxml_get_errors сообщает о проблемах FLUSH

Вывод w / python выглядит так:
python2.7 run.py

PID: 16863 aborted: 0
out_as_str: '<?xml version="1.0"?>
<Track>Highway Blues</Track>
'

out_as_file: >false<

errors:
array (
0 =>
LibXMLError::__set_state(array(
'level' => 2,
'code' => 1545,
'column' => 0,
'message' => 'flush error',
'file' => '',
'line' => 0,
))
)

Извините за длинный пост, но я весь день безуспешно просматривал код PHP / libxml2. : /

1

Решение

Причина:

Оказывается, это связано с исправлением предыдущей ошибки.

Ссылки:

Связанный php_libxml_streams_IO_write функция является writecallback (задавать в ext / libxml / libxml.c) для буфера docp объект, который передается для libxml позвонить на внутр / дом / document.c. Окончание в libxml xmlIO.c где буфер NULL следовательно файл передан для ->save(*) не пишется.

Временное решение:

Использовать ->saveXML() получить представление XML в строке и написать его, используя file_put_contents(*) рукой»:

$xml_as_str = $xml->saveXML();
file_put_contents('/tmp/my.xml', $xml_as_str);
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]