В 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. : /
Причина:
Оказывается, это связано с исправлением предыдущей ошибки.
Ссылки:
Связанный 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);
Других решений пока нет …