mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
[RFC] Implement XMLWriter::toUri() and XMLWriter::toMemory()
This commit is contained in:
2
NEWS
2
NEWS
@@ -327,7 +327,7 @@ PHP NEWS
|
||||
. Add XMLReader::fromStream(). (nielsdos)
|
||||
|
||||
- XMLWriter:
|
||||
. Add XMLWriter::toStream(). (nielsdos)
|
||||
. Add XMLWriter::toStream(), XMLWriter::toUri(), XMLWriter::toMemory(). (nielsdos)
|
||||
|
||||
- XSL:
|
||||
. Implement request #64137 (XSLTProcessor::setParameter() should allow both
|
||||
|
||||
@@ -633,7 +633,7 @@ PHP 8.4 UPGRADE NOTES
|
||||
RFC: https://wiki.php.net/rfc/xmlreader_writer_streams
|
||||
|
||||
- XMLWriter:
|
||||
. Added XMLWriter::toStream().
|
||||
. Added XMLWriter::toStream(), XMLWriter::toUri(), XMLWriter::toMemory().
|
||||
RFC: https://wiki.php.net/rfc/xmlreader_writer_streams
|
||||
|
||||
- XSL:
|
||||
|
||||
@@ -179,6 +179,18 @@ static char *_xmlwriter_get_valid_file_path(char *source, char *resolved_path, i
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void xml_writer_create_static(INTERNAL_FUNCTION_PARAMETERS, xmlTextWriterPtr writer, xmlBufferPtr output)
|
||||
{
|
||||
if (object_init_with_constructor(return_value, Z_CE_P(ZEND_THIS), 0, NULL, NULL) == SUCCESS) {
|
||||
ze_xmlwriter_object *intern = Z_XMLWRITER_P(return_value);
|
||||
intern->ptr = writer;
|
||||
intern->output = output;
|
||||
} else {
|
||||
xmlBufferFree(output);
|
||||
xmlFreeTextWriter(writer);
|
||||
}
|
||||
}
|
||||
|
||||
static const zend_module_dep xmlwriter_deps[] = {
|
||||
ZEND_MOD_REQUIRED("libxml")
|
||||
ZEND_MOD_END
|
||||
@@ -836,6 +848,36 @@ PHP_FUNCTION(xmlwriter_open_uri)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_METHOD(XMLWriter, toUri)
|
||||
{
|
||||
char *source;
|
||||
size_t source_len;
|
||||
char resolved_path[MAXPATHLEN + 1];
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_PATH(source, source_len)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (source_len == 0) {
|
||||
zend_argument_value_error(1, "cannot be empty");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
const char *valid_file = _xmlwriter_get_valid_file_path(source, resolved_path, MAXPATHLEN);
|
||||
if (!valid_file) {
|
||||
zend_argument_value_error(1, "must resolve to a valid file path");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
xmlTextWriterPtr writer = xmlNewTextWriterFilename(valid_file, 0);
|
||||
if (!writer) {
|
||||
zend_throw_error(NULL, "Could not construct libxml writer");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
xml_writer_create_static(INTERNAL_FUNCTION_PARAM_PASSTHRU, writer, NULL);
|
||||
}
|
||||
|
||||
/* {{{ Create new xmlwriter using memory for string output */
|
||||
PHP_FUNCTION(xmlwriter_open_memory)
|
||||
{
|
||||
@@ -881,6 +923,23 @@ PHP_FUNCTION(xmlwriter_open_memory)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_METHOD(XMLWriter, toMemory)
|
||||
{
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
xmlBufferPtr buffer = xmlBufferCreate();
|
||||
xmlTextWriterPtr writer = xmlNewTextWriterMemory(buffer, 0);
|
||||
|
||||
/* No need for an explicit buffer check as this will fail on a NULL buffer. */
|
||||
if (!writer) {
|
||||
xmlBufferFree(buffer);
|
||||
zend_throw_error(NULL, "Could not construct libxml writer");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
xml_writer_create_static(INTERNAL_FUNCTION_PARAM_PASSTHRU, writer, buffer);
|
||||
}
|
||||
|
||||
static int xml_writer_stream_write(void *context, const char *buffer, int len)
|
||||
{
|
||||
zend_resource *resource = context;
|
||||
@@ -927,14 +986,8 @@ PHP_METHOD(XMLWriter, toStream)
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (object_init_with_constructor(return_value, Z_CE_P(ZEND_THIS), 0, NULL, NULL) == SUCCESS) {
|
||||
ze_xmlwriter_object *intern = Z_XMLWRITER_P(return_value);
|
||||
intern->ptr = writer;
|
||||
/* output_buffer is owned by writer, and so writer will clean that up for us. */
|
||||
intern->output = NULL;
|
||||
} else {
|
||||
xmlFreeTextWriter(writer);
|
||||
}
|
||||
/* output_buffer is owned by writer, and so writer will clean that up for us. */
|
||||
xml_writer_create_static(INTERNAL_FUNCTION_PARAM_PASSTHRU, writer, NULL);
|
||||
}
|
||||
|
||||
/* {{{ php_xmlwriter_flush */
|
||||
|
||||
@@ -95,6 +95,8 @@ class XMLWriter
|
||||
*/
|
||||
public function openUri(string $uri): bool {}
|
||||
|
||||
public static function toUri(string $uri): static {}
|
||||
|
||||
/**
|
||||
* @tentative-return-type
|
||||
* @alias xmlwriter_open_memory
|
||||
@@ -102,6 +104,8 @@ class XMLWriter
|
||||
*/
|
||||
public function openMemory(): bool {}
|
||||
|
||||
public static function toMemory(): static {}
|
||||
|
||||
/** @param resource $stream */
|
||||
public static function toStream($stream): static {}
|
||||
|
||||
|
||||
13
ext/xmlwriter/php_xmlwriter_arginfo.h
generated
13
ext/xmlwriter/php_xmlwriter_arginfo.h
generated
@@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: c65d664c3c84742dfda4cb3e2682036ec4fe893a */
|
||||
* Stub hash: fcc388de55bd6d21530d16f6a9ab5f0eb307c1ff */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_xmlwriter_open_uri, 0, 1, XMLWriter, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, uri, IS_STRING, 0)
|
||||
@@ -179,9 +179,16 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_XMLWriter_openUr
|
||||
ZEND_ARG_TYPE_INFO(0, uri, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_XMLWriter_toUri, 0, 1, IS_STATIC, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, uri, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_XMLWriter_openMemory, 0, 0, _IS_BOOL, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_XMLWriter_toMemory, 0, 0, IS_STATIC, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_XMLWriter_toStream, 0, 1, IS_STATIC, 0)
|
||||
ZEND_ARG_INFO(0, stream)
|
||||
ZEND_END_ARG_INFO()
|
||||
@@ -373,6 +380,8 @@ ZEND_FUNCTION(xmlwriter_end_dtd_entity);
|
||||
ZEND_FUNCTION(xmlwriter_write_dtd_entity);
|
||||
ZEND_FUNCTION(xmlwriter_output_memory);
|
||||
ZEND_FUNCTION(xmlwriter_flush);
|
||||
ZEND_METHOD(XMLWriter, toUri);
|
||||
ZEND_METHOD(XMLWriter, toMemory);
|
||||
ZEND_METHOD(XMLWriter, toStream);
|
||||
|
||||
static const zend_function_entry ext_functions[] = {
|
||||
@@ -423,7 +432,9 @@ static const zend_function_entry ext_functions[] = {
|
||||
|
||||
static const zend_function_entry class_XMLWriter_methods[] = {
|
||||
ZEND_RAW_FENTRY("openUri", zif_xmlwriter_open_uri, arginfo_class_XMLWriter_openUri, ZEND_ACC_PUBLIC, NULL, NULL)
|
||||
ZEND_ME(XMLWriter, toUri, arginfo_class_XMLWriter_toUri, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
|
||||
ZEND_RAW_FENTRY("openMemory", zif_xmlwriter_open_memory, arginfo_class_XMLWriter_openMemory, ZEND_ACC_PUBLIC, NULL, NULL)
|
||||
ZEND_ME(XMLWriter, toMemory, arginfo_class_XMLWriter_toMemory, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
|
||||
ZEND_ME(XMLWriter, toStream, arginfo_class_XMLWriter_toStream, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
|
||||
ZEND_RAW_FENTRY("setIndent", zif_xmlwriter_set_indent, arginfo_class_XMLWriter_setIndent, ZEND_ACC_PUBLIC, NULL, NULL)
|
||||
ZEND_RAW_FENTRY("setIndentString", zif_xmlwriter_set_indent_string, arginfo_class_XMLWriter_setIndentString, ZEND_ACC_PUBLIC, NULL, NULL)
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
XMLWriter::toMemory() - custom constructor
|
||||
--EXTENSIONS--
|
||||
xmlwriter
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class CustomXMLWriter extends XMLWriter {
|
||||
public int $myField;
|
||||
|
||||
public function __construct() {
|
||||
$this->myField = 1234;
|
||||
echo "hello world\n";
|
||||
}
|
||||
}
|
||||
|
||||
$writer = CustomXMLWriter::toMemory();
|
||||
var_dump($writer);
|
||||
$writer->startElement("root");
|
||||
$writer->endElement();
|
||||
echo $writer->outputMemory();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
hello world
|
||||
object(CustomXMLWriter)#%d (1) {
|
||||
["myField"]=>
|
||||
int(1234)
|
||||
}
|
||||
<root/>
|
||||
@@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
XMLWriter::toMemory() - custom constructor error
|
||||
--EXTENSIONS--
|
||||
xmlwriter
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class CustomXMLWriter extends XMLWriter {
|
||||
public function __construct() {
|
||||
throw new Error('nope');
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
CustomXMLWriter::toMemory();
|
||||
} catch (Throwable $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
nope
|
||||
17
ext/xmlwriter/tests/xmlwriter_toMemory_normal_usage.phpt
Normal file
17
ext/xmlwriter/tests/xmlwriter_toMemory_normal_usage.phpt
Normal file
@@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
XMLWriter::toMemory() - normal usage
|
||||
--EXTENSIONS--
|
||||
xmlwriter
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$writer = XMLWriter::toMemory();
|
||||
$writer->startElement("root");
|
||||
$writer->writeAttribute("align", "left");
|
||||
$writer->writeComment("hello");
|
||||
$writer->endElement();
|
||||
echo $writer->outputMemory();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
<root align="left"><!--hello--></root>
|
||||
Reference in New Issue
Block a user