Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision |
rfc:xmlreader_writer_streams [2024/04/22 18:40] – Place under discussion nielsdos | rfc:xmlreader_writer_streams [2024/05/10 16:10] – Add example usages of the new APIs. nielsdos |
---|
====== PHP RFC: Add openStream() to XML{Reader,Writer} ====== | ====== PHP RFC: Add openStream() to XML{Reader,Writer} ====== |
* Version: 0.9 | * Version: 0.9.2 |
* Date: 2024-04-21 | * Date: 2024-04-21 |
* Author: Niels Dossche <nielsdos@php.net> | * Author: Niels Dossche <nielsdos@php.net> |
class XMLReader { | class XMLReader { |
/** @param resource $stream */ | /** @param resource $stream */ |
public static function openStream($stream, ?string $encoding = null, int $flags = 0, ?string $documentUri = null): XMLReader {} | public function openStream($stream, ?string $encoding = null, int $flags = 0, ?string $documentUri = null): void {} |
} | } |
| |
| |
The signature for <php>XMLReader::openStream()</php> is heavily inspired by the existing function <php>public static XMLReader::open(string $uri, ?string $encoding = null, int $flags = 0): bool|XMLReader</php> that operates on files. | The signature for <php>XMLReader::openStream()</php> is heavily inspired by the existing function <php>public static XMLReader::open(string $uri, ?string $encoding = null, int $flags = 0): bool|XMLReader</php> that operates on files. |
However, a major difference is that <php>XMLReader::openStream()</php> is static-only, whereas the other open functions of <php>XMLReader</php> can either be statically or non-statically called and change their return-value behaviour depending on that. As we seem to try to get away from such strange APIs, I decided to only make a static variation available. When you try to call this method non-statically, you'll get an Error to avoid confusion stating "XMLReader::openStream() can only be called statically". | However, a major difference is that <php>XMLReader::openStream()</php> is instance-method-only, whereas the other open functions of <php>XMLReader</php> can either be statically or non-statically called and change their return-value behaviour depending on that. The disadvantage of the (existing) static methods is that they can only return an instance of <php>XMLReader</php>, therefore when <php>XMLReader</php> is inherited by a user subclass we run into the problem that it doesn't return an object of the right type. Furthermore, as we seem to try to get away from such strange APIs, I decided to only make an instance method variation available. |
| |
The <php>$documentUri</php> parameter is used mostly for when libxml outputs error messages that you can put an origin name in there. | The <php>$documentUri</php> parameter is used mostly for when libxml outputs error messages that you can put an origin name in there. |
| |
The third BC break is the promotion of the NULL-byte warning to a <php>ValueError</php>. This makes the <php>XMLReader</php> and <php>XMLWriter</php> class more consistent with other extensions that throw instead of issuing a warning. The migration for developers should be quite simple: instead of silencing the warning and/or checking the return value of the function, they should use a try-catch construct to handle the error. | The third BC break is the promotion of the NULL-byte warning to a <php>ValueError</php>. This makes the <php>XMLReader</php> and <php>XMLWriter</php> class more consistent with other extensions that throw instead of issuing a warning. The migration for developers should be quite simple: instead of silencing the warning and/or checking the return value of the function, they should use a try-catch construct to handle the error. |
| |
| ===== Example usages ===== |
| |
| ==== Minimal XMLReader example ==== |
| |
| <PHP> |
| // Could be any stream, but this is for simplicity sake |
| $h = fopen("php://memory", "w+"); |
| fwrite($h, "<root><!--my comment--><child/></root>"); |
| fseek($h, 0); |
| |
| $reader = new XMLReader; |
| $reader->openStream($h); |
| |
| while ($reader->read()) { |
| switch ($reader->nodeType) { |
| case XMLReader::ELEMENT: |
| echo "Element: ", $reader->name, "\n"; |
| break; |
| case XMLReader::COMMENT: |
| echo "Comment: ", $reader->value, "\n"; |
| break; |
| } |
| } |
| </PHP> |
| |
| ==== Minimal XMLWriter example ==== |
| |
| <PHP> |
| // Could be any stream, but this is for simplicity sake |
| $h = fopen("php://output", "w"); |
| |
| $writer = new XMLWriter; |
| $writer->openStream($h); |
| |
| $writer->startElement("root"); |
| $writer->writeAttribute("align", "left"); |
| $writer->writeComment("hello"); |
| $writer->endElement(); |
| $amount = $writer->flush(); |
| echo "\nAmount of bytes written: "; |
| var_dump($amount); |
| </PHP> |
| |
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== |
===== Changelog ===== | ===== Changelog ===== |
| |
| - 0.9.2: Add example usages of the new APIs. |
| - 0.9.1: Made XMLReader::openStream() non-static instead such that it works with overridden classes. |
- 0.9: Initial version under discussion | - 0.9: Initial version under discussion |