在PHP
中,register shutdown functions的可能性(有时会被忽略)在我的场景中被定义调用,见下文。
DOMDocument class in PHP支持的PHP / libxml与我已注册的shutdown functions无法正常播放,如果我想在->save()
之后调用->saveXML()
(shutdown function
正常工作){ {3}}(例如来自已注册的destructor
或类实例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版本:
run.py
要重现user_abort 我通过 python2.7 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
php 脚本<?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--;
}
到尝试在关机功能中保存XML :
php user_aborted.php
现在,如果我运行这个脚本w / o用户中止(简单地调用PHP):
python2.7
XML得到正确保存。
然而通过python2.7 run.py
(通过退出父进程模拟用户中止)进行调用时,out_as_str
发生了最奇怪的事情:
out.xml
值很好,看起来像我想要的 libxml_get_errors
是空文件 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,
))
)
报告FLUSH问题输出w / python看起来: python2.7 run.py
{{1}}
很抱歉这篇长篇文章,但我一整天都在查看PHP / libxml2代码,但没有成功。 :/ 的
答案 0 :(得分:1)
原因:
事实证明这是由于修复了以前的错误。
链接:
链接的php_libxml_streams_IO_write
函数是writecallback
(设置为in ext/libxml/libxml.c),用于docp
对象的缓冲区,用于libxml
调用在ext/dom/document.c。在缓冲区为NULL
的{{3}}中结束,因此->save(*)
的文件不会被写入。
解决方法:
使用->saveXML()
以字符串形式获取XML表示形式,并使用{#1}}通过&#34; hand&#34;
file_put_contents(*)