处理user_abort后,DOMDocument-> save()失败

时间:2017-05-03 16:39:11

标签: php xml libxml2 php-7

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代码,但没有成功。 :/

1 个答案:

答案 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(*)