From 3a130bd6b1ff3255fb66ee32c3ec4feeea71d9ff Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 1 Mar 2022 18:28:30 +0100 Subject: [PATCH] docs: tutorial --- docs/Makefile | 21 +- docs/tutorial/: Tutorial.md | 192 +++++++++++ .../: Tutorial/:1. Getting started.md | 131 ++++++++ docs/tutorial/: Tutorial/:2. What is ion.md | 215 +++++++++++++ .../: Tutorial/:3. Standard Datatypes.md | 290 +++++++++++++++++ .../: Tutorial/:4. Special Datatypes.md | 303 ++++++++++++++++++ .../:5. Symbols, Tables and Catalogs.md | 269 ++++++++++++++++ docs/v0.1/index.html | 2 +- docs/v0.1/ion.html | 11 +- docs/v0.1/ion.stub.php | 14 +- docs/v0.1/ion/: Contributing.html | 2 + docs/v0.1/ion/: Security.html | 2 + docs/v0.1/ion/: Tutorial.html | 166 ++++++++++ .../ion/: Tutorial/:1. Getting started.html | 147 +++++++++ docs/v0.1/ion/: Tutorial/:2. What is ion.html | 163 ++++++++++ .../v0.1/ion/: Tutorial/:2. What is ion?.html | 131 ++++++++ docs/v0.1/ion/: Tutorial/:3. Datatypes.html | 161 ++++++++++ .../: Tutorial/:3. Standard Datatypes.html | 160 +++++++++ .../ion/: Tutorial/:4. Special Datatypes.html | 166 ++++++++++ .../:4. Symbols, Tables and Catalogs.html | 116 +++++++ .../:5. Symbols, Tables and Catalogs.html | 137 ++++++++ docs/v0.1/ion/: Tutorial/Untitled.html | 111 +++++++ docs/v0.1/ion/Catalog.html | 2 + docs/v0.1/ion/Decimal.html | 2 + docs/v0.1/ion/Exception.html | 2 + docs/v0.1/ion/LOB.html | 2 + docs/v0.1/ion/Reader.html | 2 + docs/v0.1/ion/Serializer.html | 2 + docs/v0.1/ion/Serializer/PHP.html | 4 +- docs/v0.1/ion/Serializer/PHP/__construct.html | 4 +- docs/v0.1/ion/Symbol.html | 2 + docs/v0.1/ion/Timestamp.html | 4 +- docs/v0.1/ion/Timestamp/__construct.html | 4 +- docs/v0.1/ion/Type.html | 4 +- docs/v0.1/ion/Unserializer.html | 2 + docs/v0.1/ion/Unserializer/PHP.html | 4 +- .../ion/Unserializer/PHP/__construct.html | 4 +- docs/v0.1/ion/Writer.html | 2 + docs/v0.1/ion/serialize.html | 6 +- docs/v0.1/ion/unserialize.html | 6 +- 40 files changed, 2935 insertions(+), 33 deletions(-) create mode 100644 docs/tutorial/: Tutorial.md create mode 100644 docs/tutorial/: Tutorial/:1. Getting started.md create mode 100644 docs/tutorial/: Tutorial/:2. What is ion.md create mode 100644 docs/tutorial/: Tutorial/:3. Standard Datatypes.md create mode 100644 docs/tutorial/: Tutorial/:4. Special Datatypes.md create mode 100644 docs/tutorial/: Tutorial/:5. Symbols, Tables and Catalogs.md create mode 100644 docs/v0.1/ion/: Tutorial.html create mode 100644 docs/v0.1/ion/: Tutorial/:1. Getting started.html create mode 100644 docs/v0.1/ion/: Tutorial/:2. What is ion.html create mode 100644 docs/v0.1/ion/: Tutorial/:2. What is ion?.html create mode 100644 docs/v0.1/ion/: Tutorial/:3. Datatypes.html create mode 100644 docs/v0.1/ion/: Tutorial/:3. Standard Datatypes.html create mode 100644 docs/v0.1/ion/: Tutorial/:4. Special Datatypes.html create mode 100644 docs/v0.1/ion/: Tutorial/:4. Symbols, Tables and Catalogs.html create mode 100644 docs/v0.1/ion/: Tutorial/:5. Symbols, Tables and Catalogs.html create mode 100644 docs/v0.1/ion/: Tutorial/Untitled.html diff --git a/docs/Makefile b/docs/Makefile index 45dd2f6..02805ea 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -5,7 +5,14 @@ TAG := $(shell (git describe --tags --match=v[0-9]* 2>/dev/null || git tag --so # --- -SPECIAL_SRC := src/ion/\\\:\\\ Security.md src/ion/\\\:\\\ Contributing.md src/ion.md src/mdref.json +SPECIAL_SRC := \ + src/mdref.json \ + src/ion.md \ + src/ion/\\\:\\\ Contributing.md \ + src/ion/\\\:\\\ Security.md \ + tutorial + +# --- .PHONY: all all: latest @@ -26,7 +33,7 @@ $(TAG): markdown | vendor/bin/ref2html markdown: src/ion.stub.php $(SPECIAL_SRC) | vendor/bin/stub2ref $(PHP) $| ion $< src -src src/ion: +src src/ion src/ion/\\\:\\\ Tutorial: -mkdir -p $@ src/mdref.json: mdref.json -test -e $@ || ln $^ $@ @@ -34,10 +41,14 @@ src/ion.stub.php: ../ion.stub.php | src -test -e $@ || ln $^ $@ src/ion.md: ../README.md | src -test -e $@ || ln $^ $@ -src/ion/\\\:\\\ Security.md: ../SECURITY.md | src/ion - -test -e $@ || ln $^ $@ src/ion/\\\:\\\ Contributing.md: ../CONTRIBUTING.md | src/ion -test -e $@ || ln $^ $@ +src/ion/\\\:\\\ Security.md: ../SECURITY.md | src/ion + -test -e $@ || ln $^ $@ + +.PHONY: tutorial +tutorial: | src/ion + cp -R tutorial/* src/ion/ vendor/%: COMPOSER= $(COMPOSER) require m6w6/mdref:dev-master @@ -51,5 +62,3 @@ docker: .PHONY: clean clean: -rm -rf latest src vendor composer* .composer - - diff --git a/docs/tutorial/: Tutorial.md b/docs/tutorial/: Tutorial.md new file mode 100644 index 0000000..707b358 --- /dev/null +++ b/docs/tutorial/: Tutorial.md @@ -0,0 +1,192 @@ +# Tutorial + +Welcome to the ext-ion tutorial. We'll look into what Amazon's ION format is and how to use it from within PHP. + +1. ★1. [Getting started](ion/:%20Tutorial/:1.%20Getting%20started) +2. ★2. [What is ion?](ion/:%20Tutorial/:2.%20What%20is%20ion) +3. ★3. [Standard Datatypes](ion/:%20Tutorial/:3.%20Standard%20Datatypes) +4. ★4. [Special Datatypes](ion/:%20Tutorial/:4.%20Special%20Datatypes) +4. ★5. [Symbols, Tables and Catalogs](ion/:%20Tutorial/:4.%20Symbols,%20Tables%20and%20Catalogs) + + + +> Parts of this documentation are replicated verbatim of the official [Amazon ION documentation](https://amzn.github.io/ion-docs/) licensed under the Apache 2.0 License. + +``` + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS +``` diff --git a/docs/tutorial/: Tutorial/:1. Getting started.md b/docs/tutorial/: Tutorial/:1. Getting started.md new file mode 100644 index 0000000..0b24ca6 --- /dev/null +++ b/docs/tutorial/: Tutorial/:1. Getting started.md @@ -0,0 +1,131 @@ +# Getting started + +The PHP extension for Ion requires **PHP version 8.1** or greater, see the [Install](ion/:%20Tutorial/:1.%20Getting%20started#Install) section. + +## Why Ion? + +- Ion provides **[dual-format interoperability](ion/:%20Tutorial/:1.%20Getting%20started#Dual-format.interoperability)**, which enables users to take advantage of the ease of use of the text format while capitalizing on the efficiency of the binary format. The text form is easy to prototype, test, and debug, while the binary format saves space and parsing effort. +- Ion’s **[rich type system](ion/:%20Tutorial/:1.%20Getting%20started#Rich.type.system)** extends JSON’s, adding support for types that make Ion suitable for a wider variety of uses, including precision-sensitive applications and portability across languages and runtimes. +- Ion is a **[self-describing](ion/:%20Tutorial/:1.%20Getting%20started#Self-describing)** format, giving its readers and writers the flexibility to exchange Ion data without needing to agree on a schema in advance. Ion’s “open-content” supports discovery, deep component chaining, and schema evolution. +- Because most data is read more often than it is written, Ion defines a **[read-optimized binary format](ion/:%20Tutorial/:1.%20Getting%20started#Read-optimized.binary.format)**. + +### Dual-format interoperability + +Applications can seamlessly consume Ion data in either its text or binary forms without loss of data fidelity. While the expectation is that most Ion data is in binary form, the text form promotes human readability, simplifying discovery and diagnosis. + +Notably, the text format is a superset of JSON, making all JSON data valid Ion data. You probably already know how to read and author Ion. + +#### Ease of use + +Like JSON, Ion’s text format is concise and clearly legible. It is intelligible to humans and may be edited using familiar tools like a text editor. This makes Ion well-suited to rapid prototyping: developers can quickly mock up the their data in text Ion, knowing that their application will ultimately seamlessly process the more efficient binary Ion format. Once the application is up and running, the users can debug it by intercepting the binary Ion data and converting it to text Ion with full fidelity. After analysis, hand-edited records can be re-inserted into a processing pipeline as needed to support debugging and prototyping. + +Text-only formats are more expensive to parse, which is why Ion offers the option of the length-prefixed binary format. This binary format supports rapid skip-scanning of data to materialize only key values within Ion streams. + +#### Seamless transcoding + +Ion’s interoperable formats avoid the kinds of semantic mismatches encountered when attempting to mix and match separate text and binary formats. + +Standalone binary formats such as [CBOR](http://cbor.io/) sacrifice human-readability in favor of an encoding that is more compact and efficient to parse. Although CBOR is based on JSON, transcoding between the two is not always straightforward because CBOR’s more expressive types do not necessarily map cleanly to JSON types. For example, CBOR’s `bignum` must be base-64 encoded and represented as a JSON `string` in order to avoid numeric overflow when read by a JSON parser, while a CBOR `map` may be directly converted to a JSON `object` only if all its keys are UTF-8 strings. + +### Rich type system + +Ion’s type system is a superset of JSON’s: in addition to strings, booleans, arrays (lists), objects (structs), and nulls, Ion adds support for arbitrary-precision timestamps, embedded binary values (blobs and clobs), and symbolic expressions. Ion also expands JSON’s `number` specification by defining distinct types for arbitrary-size integers, IEEE-754 binary floating point numbers, and infinite-precision decimals. Decimals are particularly useful for precision-sensitive applications such as financial transaction record-keeping. JSON’s `number` type is underspecified; in practice, many implementations represent all JSON numbers as fixed-precision base-2 floats, which are subject to rounding errors and other loss of precision. + +#### Timestamps + +Ion [timestamps](ion/:%20Tutorial/:4.%20Special%20Datatypes#Timestamps) are W3C-compliant representations of calendar dates and time, supporting variable precision including year, month, day, hours, minutes, seconds, and fractional seconds. Ion timestamps may optionally encode a time zone offset. + +By defining timestamps as a distinct type, Ion eliminated the ambiguity involved with representing dates as strings, as the semantics are clearly defined. Unlike a number, which counts from some “epoch”, arbitrary precision timestamps also allow applications to represent deliberate ambiguity. + +#### Blobs and Clobs + +Ion’s [`blob`](ion/:%20Tutorial/:4.%20Special%20Datatypes#BLob) and [`clob`](ion/:%20Tutorial/:4.%20Special%20Datatypes#CLob) types allow applications to tunnel binary data through Ion. This allows such applications to transmit opaque binary payloads (e.g. media, code, and non-UTF-8 text) in Ion without the need to apply additional processing to the payloads to make them conform to a different Ion type. + +For example, a `blob` could be used to transmit a bitmap image, while a `clob` could be used to transmit Shift JIS text or an XML payload. + +#### Symbolic expressions + +The Ion specification defines a distinct syntax for [symbolic expression](ion/:%20Tutorial/:4.%20Special%20Datatypes#S-Expressions)s (*S-expressions*), but does not define how they should be processed. This allows applications to use S-expressions to convey domain-specific semantics in a first-class Ion type. + +Formats that lack S-expressions as a first-class type are often left to choose between two imperfect options: adding a pre-processor (e.g. [Jsonnet](http://jsonnet.org/) on top of JSON) to work around the inability to represent expressions as data, or tunneling domain-specific language text as opaque strings or binary payloads. + +#### Annotations + +The Ion specification provides a formal mechanism for applications to annotate any Ion value without the need to enclose the value in a container. These *annotations* are not interpreted by Ion readers and may be used, for example, to add type information to a `struct`, time units to an integer or decimal value, or a description of the contents of a blob value. + +### Self-describing + +Like JSON and CBOR, Ion is a self-describing format, meaning that it does not require external metadata (i.e. a schema) in order to interpret the structural characteristics of data denoted by the format. Notably, Ion payloads are free from build-time binding that inhibits independent innovation and evolution across service boundaries. This provides greater flexibility over schema-based formats such as [protocol buffers](https://developers.google.com/protocol-buffers/), [Thrift](http://thrift.apache.org/), and [Avro](https://avro.apache.org/), as data may be sparsely encoded and the implicit schema may be changed without explicit renegotiation of the schema among all consumers. These benefits come at the cost of a less compact encoding, but in our experience the positive impact on agility has been more valuable than an efficient but brittle contract. + +### Read-optimized binary format + +Ion’s binary format is optimized according to the following principles: + +- Most data is read far more often than it is written. Generally, with the exception of logs, any data which is written is read at least once. Read multipliers are common in processing pipelines, workflows, and shared data marts. +- Many reads are shallow or sparse, meaning that the application is focused on only a subset of the values in the stream, and that it can quickly determine if full materialization of a value is required. + +In the spirit of these principles, the Ion specification includes features that make Ion’s binary encoding more efficient to read than other schema-free formats. These features include length-prefixing of binary values and Ion’s use of symbol tables. + +#### Length-prefixing + +Because most reads are sparse, binary Ion invests some encoding space to length-prefix each value in a stream. This makes seeking to the next relevant value for a particular application inexpensive, and enables efficient skip-scanning of data. This allows applications to cherry-pick only the relevant values from the stream for deeper parsing, and to economize parsing of irrelevant values. + +#### Symbol tables + +In binary Ion, common text tokens such as struct field names are automatically stored in a symbol table. This allows these tokens to be efficiently encoded as table offsets instead of repeated copies of the same text. As a further space optimization, symbol tables can be pre-shared between producer and consumer so that only the table name and version are included in the payload, eliminating the overhead involved with repeatedly defining the same symbols across multiple pieces of Ion data. + +## Install + +You can get started installing ext-ion the usual ways: + +### PECL + +`pecl install ion` + +### Trinity + +```shell +./configure +make #-j$(nproc) +sudo make install #INSTALL=install +``` + +### PHARext + +See https://pharext.org and https://replicator.pharext.org/?ion + +#### Quick: + +```sh +curl -sSO https://replicator.pharext.org/phars/ion/ion-0.1.0.ext.phar +php ./ion-0.1.0.ext.phar --sudo --ini +``` + +#### Verified: + +```sh +# download phar, signature and public key +curl -sSO https://replicator.pharext.org/replicator.pub +curl -sSO https://replicator.pharext.org/phars/ion/ion-0.1.0.ext.phar +curl -sSO https://replicator.pharext.org/sigs/ion/ion-0.1.0.ext.phar.sig + +# verify signature against public key +openssl dgst \ + -verify replicator.pub \ + -signature ion-0.1.0.ext.phar.sig \ + ion-0.1.0.ext.phar + +# install verified extension +php ./ion-0.1.0.ext.phar --sudo --ini + +``` + +## Check + +`php -m | grep ^ion` should show: `ion`. + +--- + +## Next up + +* [What is ion?](ion/:%20Tutorial/:2.%20What%20is%20ion) \ No newline at end of file diff --git a/docs/tutorial/: Tutorial/:2. What is ion.md b/docs/tutorial/: Tutorial/:2. What is ion.md new file mode 100644 index 0000000..b43bac9 --- /dev/null +++ b/docs/tutorial/: Tutorial/:2. What is ion.md @@ -0,0 +1,215 @@ +# What Is Ion? + +Quoting the [official Ion documentation](https://amzn.github.io/ion-docs/): + +**Amazon Ion** is a [richly-typed](ion/:%20Tutorial/:1.%20Getting%20started#Rich.type.system), [self-describing](ion/:%20Tutorial/:1.%20Getting%20started#Self-describing), hierarchical data serialization format offering [interchangeable binary and text](https://amzn.github.io/ion-docs/guides/why.html#dual-format-interoperability) representations. The [text format](https://amzn.github.io/ion-docs/docs/spec.html) (a superset of [JSON](http://json.org/)) is easy to read and author, supporting rapid prototyping. + +The [binary representation](https://amzn.github.io/ion-docs/docs/binary.html) is [efficient to store, transmit, and skip-scan parse](https://amzn.github.io/ion-docs/guides/why.html#read-optimized-binary-format). + +The rich type system provides unambiguous semantics for longterm preservation of data which can survive multiple generations of software evolution. + +Ion was built to address rapid development, decoupling, and efficiency challenges faced every day while engineering large-scale, service-oriented architectures. + +### Some simple examples + +#### Serialization: + +```php + "value", + "more" => [ + "data" => 123 + ] +]); +?> +``` + +##### Output: + +```json +{key:"value",more:{data:123}} +``` + +If you now think that this looks a lot like JSON, you're probably right, because Ion is a superset of JSON: + +```php + "value", + "more" => [ + "data" => 123 + ] +]); +?> +``` + +##### Output: + +```json +{"key":"value","more":{"data":123}} +``` + +So, all valid JSON is also valid Ion. Please refer to the [official spec](https://amzn.github.io/ion-docs/docs/spec.html) to learn more about this topic. + +#### Unserialization: + +```php + +``` + +##### Output: + +```php +[ + 'key' => 'value', + 'more' => [ + 'data' => 123, + ], +] +``` + +If you try the same with the JSON equivalent, you'll see that it's basically valid Ion, too: + +```php + +``` + +##### Output: + +```php +[ + 'key' => 'value', + 'more' => [ + 'data' => 123, + ], +] +``` + +### Multiple documents + +Ion supports multiple sequences of documents within a single stream; consider the following: + +```php + +``` + +#### Output: + +```php +[ + [ + 'key' => 'value', + 'more' => [ + 'data' => 123, + ], + ], + [ + 'key' => 'value', + 'more' => [ + 'data' => 456, + ], + ], +] +``` + +### Annotations + +Any Ion value can include one or more annotation symbols denoting the semantics of the content. This can be used to: + +- Annotate individual values with schema types, for validation purposes. +- Associate a higher-level datatype (e.g. a Java class) during serialization processes. +- Indicate the notation used within a `blob` or `clob` value. +- Apply other application semantics to a single value. + +In the text format, type annotations are denoted by a non-null symbol token and double-colons preceding any value. Multiple annotations on the same value are separated by double-colons: + +``` +int32::12 // Suggests 32 bits as end-user type +degrees::'celsius'::100 // You can have multiple annotaions on a value +'my.custom.type' :: { x : 12 , y : -1 } // Gives a struct a user-defined type + +{ field: some_annotation::value } // Field's name must precede annotations of its value + +jpeg :: {{ ... }} // Indicates the blob contains jpeg data +bool :: null.int // A very misleading annotation on the integer null +'' :: 1 // An empty annotation +null.symbol :: 1 // ERROR: type annotation cannot be null +``` + +Except for a small number of predefined system and PHP annotations, Ion itself neither defines nor validates such annotations; that behavior is left to applications or tools (such as schema validators). + +It’s important to understand that annotations are symbol *tokens*, not symbol *values*. That means they do not have annotations themselves. In particular, the text `a::c` is a single value consisting of three textual tokens (a symbol, a double-colon, and another symbol); the first symbol token is an *annotation* on the value, and the second is the *content* of the value. + +#### System Annotations + +```php + %s\n", $e->value, $e->name); +} + +/* + $ion:: => Ion + $ion_1_0:: => Ivm_1_0 + $ion_symbol_table:: => IonSymbolTable + name:: => Name + version:: => Version + imports:: => Imports + symbols:: => Symbols + max_id:: => MaxId + $ion_shared_symbol_table:: => SharedSymbolTable +*/ + +?> +``` + +#### PHP Annotations + +There are two handful of annotations used by PHP, which are centralized in the ion\Symbol\PHP enumeration: + +```php + %s\n", $e->value, $e->name); +} + +/* + PHP:: => PHP + R:: => Reference + r:: => Backref + p:: => Property + o:: => Object + c:: => ClassObject + O:: => MagicObject + C:: => CustomObject + E:: => Enum + S:: => Serializable +*/ + +?> +``` + +--- + +## Next up + +* [Standard Datatypes](ion/:%20Tutorial/:3.%20Standard%20Datatypes) diff --git a/docs/tutorial/: Tutorial/:3. Standard Datatypes.md b/docs/tutorial/: Tutorial/:3. Standard Datatypes.md new file mode 100644 index 0000000..1b888af --- /dev/null +++ b/docs/tutorial/: Tutorial/:3. Standard Datatypes.md @@ -0,0 +1,290 @@ +# Standard Datatypes + +ION supports many of PHP's data types: + +## Nulls + +Additonally to the plain and simple `NULL`, ION can attach a type to `NULL` values. + +```php +writeNull(); +$writer->writeTypedNull(ion\Type::Int); +$writer->writeTypedNull(ion\Type::String); +$writer->flush(); + +/* + null + null.int + null.string +*/ + +?> +``` + +## Booleans + +The bool type does not need a lot of explanation: + +```php +writeBool(true); +$writer->writeBool(false); +$writer->flush(); + +/* + true + false +*/ + +?> +``` + +## Integers + +The int type comprises signed integers of arbitrary size. + +```php +writeInt(123); +$writer->writeInt("12345678901234567890"); +$writer->flush(); + +/* + 123 + 12345678901234567890 +*/ + +?> +``` + +In ION-Text, underscores are allowed to separate digits: + +```php +next(); +var_dump($reader->getType()); +var_dump($reader->readInt()); + +/* + enum(ion\Type::Int) + int(-123456789) +*/ + +?> +``` + +Hexadecimal as well as binary notation are supported, too: + +```php +next(); +var_dump($reader->readInt()); + +/* + int(3735928559) +*/ + +$reader = new ion\Reader\Buffer\Reader("0b10000100_11001001"); +$reader->next(); +var_dump($reader->readInt()); + +/* + int(33993) +*/ + +?> +``` + +## Reals + +Ion supports both binary and lossless decimal encodings of real numbers as, respectively, types `float` and `decimal`. In the text format, `float` values are denoted much like the decimal formats in C or Java; `decimal` values use `d` instead of `e` to start the exponent. + +Reals without an exponent are treated as decimal. As with JSON, extra leading zeros are not allowed. Digits may be separated with an underscore. + +### Floats + +```php + + float(0.123) + [1]=> + float(0.123) + } +*/ + +?> +``` + +### Decimals + +```php + + object(ion\Decimal)#8 (2) { + ["number"]=> + string(5) "0.123" + // ... + } + [1]=> + object(ion\Decimal)#11 (2) { + ["number"]=> + string(5) "0.123" + // ... + } + } +*/ + +?> +``` + +## Strings + +Ion strings are Unicode character sequences of arbitrary length. + +In the text format, strings are delimited by double-quotes and follow common backslash-escape conventions (see [official spec](https://amzn.github.io/ion-docs/docs/spec.html#escapess)). The binary format always uses UTF-8 encoding. + +```php + +``` + +### Long Strings + +The text format supports an alternate syntax for “long strings”, including those that break across lines. Sequences bounded by three single-quotes (''') can cross multiple lines and still count as a valid, single string. In addition, any number of adjacent triple-quoted strings are concatenated into a single value. + +The concatenation happens within the Ion text parser and is neither detectable via the data model nor applicable to the binary format. Note that comments are always treated as whitespace, so concatenation still occurs when a comment falls between two long strings. + +```php + +``` + +## Containers + +Ion defines three container types: structures, lists, and S-expressions. These types are defined recursively and may contain values of any Ion type. + +### Lists + +Lists are ordered collections of values. The contents of the list are heterogeneous (that is, each element can have a different type). In the text format, lists are bounded by square brackets and elements are separated by commas. + +```php + +``` + +### Structures + +Structures are *unordered* collections of name/value pairs. The names are symbol tokens, and the values are unrestricted. Each name/value pair is called a field. + +In the text format, structures are wrapped by curly braces, with a colon between each name and value, and a comma between the fields. For the purposes of JSON compatibility, it’s also legal to use strings for field names, but they are converted to symbol tokens by the parser. + +```php + "value", + "obj" => (object)["key" => "value"] +]); + +/* + {'0':"outlaw",key:"value",obj:o::{key:"value"}} +*/ + +?> +``` + +```php + + string(6) "outlaw" + ["key"]=> + string(5) "value" + ["obj"]=> + object(stdClass)#10 (1) { + ["key"]=> + string(5) "value" + } + } +*/ + +?> +``` + +--- + +## Next up + +* [Special Datatypes](ion/:%20Tutorial/:4.%20Special%20Datatypes) diff --git a/docs/tutorial/: Tutorial/:4. Special Datatypes.md b/docs/tutorial/: Tutorial/:4. Special Datatypes.md new file mode 100644 index 0000000..8cfe131 --- /dev/null +++ b/docs/tutorial/: Tutorial/:4. Special Datatypes.md @@ -0,0 +1,303 @@ +# Special Datatypes + +There are a handful of data types treated in a specific way in PHP; consider the following examples: + +## Symbols + +Symbols are much like strings, in that they are Unicode character sequences. The primary difference is the intended semantics: symbols represent semantic identifiers as opposed to textual literal values. Symbols are case sensitive. + +In the text format, symbols are delimited by single-quotes and use the same [escape characters](https://amzn.github.io/ion-docs/docs/spec.html#escapes). + +See [Ion Symbols](https://amzn.github.io/ion-docs/docs/symbols.html) for more details about symbol representations and symbol tables, and our section on [Symbols, Tables and Catalogs](ion/:%20Tutorial/:5.%20Symbols,%20Tables%20and%20Catalogs) for a distilled read. + +## Decimals + +See the [section on reals](ion/:%20Tutorial/:3.%20Standard%20Datatypes#Reals) for an introduction. + +```php +isInt() ? "int" : "noint", "\n"; +// 123d0 = int + +$d = new ion\Decimal("123.123"); +echo ion\serialize($d), " = ", $d->isInt() ? "int" : "noint" ,"\n"; +// 123.123 = noint + +?> +``` + +See the [official ION spec about real numbers](https://amzn.github.io/ion-docs/docs/spec.html#real-numbers) and also [Ion Float](https://amzn.github.io/ion-docs/docs/float.html) and [Ion Decimals](https://amzn.github.io/ion-docs/docs/decimal.html) for more notes. + +## LOBs + +### BLob + +The `blob` type allows embedding of arbitrary raw binary data. Ion treats such data as a single (though often very large) value. It does no processing of such data other than passing it through intact. + +In the text format, `blob` values are denoted as [RFC 4648](https://tools.ietf.org/html/rfc4648)-compliant [Base64](http://en.wikipedia.org/wiki/Base64) text within two pairs of curly braces. + +``` +{{ dHdvIHBhZGRpbmcgY2hhcmFjdGVycw== }} +``` + +### CLob + +The `clob` type is similar to `blob` in that it holds uninterpreted binary data. The difference is that the content is expected to be text, so we use a text notation that’s more readable than Base64. + +``` +{{ "This is a CLOB of text." }} +``` + +See the official ION specification on [Blobs](https://amzn.github.io/ion-docs/docs/spec.html#blob) and [Clobs](https://amzn.github.io/ion-docs/docs/spec.html#clob). + +## Timestamps + +Timestamps represent a specific moment in time, always include a local offset, and are capable of arbitrary precision. + +Instances of ion\Timestamp are really just plain \DateTime objects augmented with Stringable and ION specific formatting. + +```php + +``` + +```php + +``` + +```php + +``` + +See also the [official ION Timestamp specification](https://amzn.github.io/ion-docs/docs/spec.html#timestamp). + +## Special PHP Objects + +### Deprecated Serializable: + +> ***NOTE:*** +> The interface Serializable has been deprecated in 8.1 and should be replaced with magic serialize methods. + +```php +data = $data; + } +} + +$srlzbl = new srlzbl; +var_dump($srlzbl); + +$srlzd = ion\serialize($srlzbl); +echo $srlzd; + +/* + object(srlzbl)#4 (1) { + ["data":"srlzbl":private]=> + string(3) "foo" + } + + S::srlzbl::{{"bar"}} + +*/ + +?> +``` + +Everything as expected so far, Serializable return a string, but since they cannot indicate whether it's a valid UTF-8 string, a ion\Type::CLob or ion\Type::BLob, CLobs are assumed. + +Unserialization does not offer any surprises, either: + +```php + + string(3) "bar" + } + +*/ + +?> +``` + +### Magic __serialize: + +Implementing serialization behavior with magic methods is the preferred way since 8.1: + +```php + "bar"]; + } + function __unserialize(array $data) : void { + foreach ($data as $k => $v) + $this->$k = $v; + } +} + +$magic = new magic; +var_dump($magic); + +$srlzd = ion\serialize($magic); +echo $srlzd; + +/* + object(magic)#6 (1) { + ["foo":"magic":private]=> + string(3) "foo" + } + + O::magic::{foo:"bar"} + +*/ + +?> +``` + +Again, unserialization yields the expected results: + +```php + + string(3) "bar" + } + +*/ + +?> +``` + +### Custom serialize: + +Customly serializable objects work like magic serializable objects, with custom names for the magic methods. + +```php +data = $data; + } + function export() : array { + return $this->data; + } +} + +$custom = new custom; +$custom->init(["foo" => "bar"]); +echo $srlzd = ion\serialize($custom); + +/* + c::custom::{data:p::custom::{foo:"bar"}} + +*/ + +?> +``` + +The above is actually the result of serializing a standard class backed PHP object, because we didn't implement any serialization primitives and did neither specify a custom method to call. So let's just do that: + +```php + +``` + +Note how this output compares to the output of the standard magic serializable object. + +Unserialization works as used to, except sepcifying thwe custom unserialization method to call: + +```php + + array(1) { + ["foo"]=> + string(3) "bar" + } + } + +*/ + +?> +``` + +## S-Expressions + +An S-expression (or [symbolic expression](https://en.wikipedia.org/wiki/S-expression)) is much like a list in that it’s an ordered collection of values. However, the notation aligns with Lisp syntax to connote use of application semantics like function calls or programming-language statements. As such, correct interpretation requires a higher-level context other than the raw Ion parser and data model. + +In the text format, S-expressions are bounded by parentheses. S-expressions also allow unquoted operator symbols (in addition to the unquoted identifier symbols allowed everywhere), so commas are interpreted as values rather than element separators. + +``` +null.sexp // A null S-expression value +() // An empty expression value +(cons 1 2) // S-expression of three values +([hello][there]) // S-expression containing two lists + +(a+-b) ( 'a' '+-' 'b' ) // Equivalent; three symbols +(a.b;) ( 'a' '.' 'b' ';') // Equivalent; four symbols +``` + +Although Ion S-expressions use a syntax similar to Lisp expressions, Ion does not define their interpretation or any semantics at all, beyond the pure sequence-of-values data model indicated above. + +--- + +## Next up + +* [Symbols, Tables and Catalogs](ion/:%20Tutorial/:5.%20Symbols,%20Tables%20and%20Catalogs) \ No newline at end of file diff --git a/docs/tutorial/: Tutorial/:5. Symbols, Tables and Catalogs.md b/docs/tutorial/: Tutorial/:5. Symbols, Tables and Catalogs.md new file mode 100644 index 0000000..637a098 --- /dev/null +++ b/docs/tutorial/: Tutorial/:5. Symbols, Tables and Catalogs.md @@ -0,0 +1,269 @@ +# Symbols, Tables and Catalogs + +## Schematic Overview + +``` + +---------+ + | Catalog | + +----+----+-------------------------------+ + | | | + | | +-------------+ | + | +--->| SymbolTable | | + | | +---+---------+---------------+ | + | | | | | | + | | | | +-------------------+ | + | | | | | Symbol (ID, Text) | | + | | | +---->| Symbol (ID, Text) | | + | | | | ... | | + | | +---------+-------------------+ | + | | | + | | +-------------+ | + | +--->| SymbolTable | | + | | +---+---------+---------------+ | + | | | | | | + | . | | +-------------------+ | + | . | +---->| Symbol (ID, Text) | | + | . | | ... | | + | . +---------+-------------------+ | + | . | + +-----------------------------------------+ +``` + +## Catalog + +The Catalog holds a collection of ion\Symbol\Table instances queried from ion\Reader and ion\Writer instances. + +See also [the ION spec's symbol guide chapter on catalogs](https://amzn.github.io/ion-docs/docs/symbols.html#the-catalog). + +``` php +add($symtab); +?> +``` + +## Symbol Table + +There are three types of symbol tables: + +- Local +- Shared +- System (a special shared symbol table) + +Local symbol tables do not have names, while shared symbol tables require them; only shared symbol tables may be added to a catalog or to a writer’s list of imports. + +Local symbol tables are managed internally by Ion readers and writers. No application configuration is required to tell Ion readers or writers that local symbol tables should be used. + +### Using a shared symbol table + +Using local symbol tables requires the local symbol table (including all of its symbols) to be written at the beginning of the value stream. Consider an Ion stream that represents CSV data with many columns. Although local symbol tables will optimize writing and reading each value, including the entire symbol table itself in the value stream adds overhead that increases with the number of columns. + +If it is feasible for the writers and readers of the stream to agree on a pre-defined shared symbol table, this overhead can be reduced. + +Consider the following CSV in a file called `test.csv`. + +``` + id,type,state + 1,foo,false + 2,bar,true + 3,baz,true + ... +``` + +An application that wishes to convert this data into the Ion format can generate a symbol table containing the column names. This reduces encoding size and improves read efficiency. + +Consider the following shared symbol table that declares the column names of `test.csv` as symbols. Note that the shared symbol table may have been generated by hand or programmatically. + +``` + $ion_shared_symbol_table::{ + name: "test.csv.columns", + version: 1, + symbols: ["id", "type", "state"], + } +``` + +This shared symbol table can be stored in a file (or in a database, etc.) to be resurrected into a symbol table at runtime. + +Because the value stream written using the shared symbol table does not contain the symbol mappings, a reader of the stream needs to access the shared symbol table using a catalog. + +Consider the following complete example: + +```php +add($symtab); + +/* Use the catalog when writing the data */ +$writer = new class(options: new ion\Writer\Options( + catalog: $catalog, + outputBinary: true +)) extends ion\Writer\Buffer\Writer { + public function writeRow(Row $row) : void { + $this->startContainer(ion\Type::Struct); + + $this->writeFieldname("id"); + $this->writeInt($row->id); + + $this->writeFieldName("type"); + $this->writeString($row->type); + + $this->writeFieldName("state"); + $this->writeBool($row->state); + + $this->finishContainer(); + } +}; + +$writer->writeRow(new Row(1, "foo", false)); +$writer->writeRow(new Row(2, "bar")); +$writer->writeRow(new Row(3, "baz")); +$writer->flush(); + +?> +``` + +Let's inspect the binary ION stream and verify that the column names are actually replaced by SymbolIDs: + +```php +getBuffer(), 8) as $line) { + printf("%-26s", chunk_split(bin2hex($line), 2, " ")); + foreach (str_split($line) as $byte) { + echo $byte >= ' ' && $byte <= '~' ? $byte : "."; + } + echo "\n"; +} +echo "\n"; + +/* + e0 01 00 ea ee a2 81 83 ........ \ + de 9e 86 be 9b de 99 84 ........ | + 8e 90 74 65 73 74 2e 63 ..test.c > here's ION symbol table metadata + 73 76 2e 63 6f 6c 75 6d sv.colum | + 6e 73 85 21 01 88 21 03 ns.!..!. < + da 8a 21 01 8b 83 66 6f ..!...fo | + 6f 8c 11 da 8a 21 02 8b o....!.. > here's the actual data + 83 62 61 72 8c 11 da 8a .bar.... | + 21 03 8b 83 62 61 7a 8c !...baz. / + 11 . +*/ + +?> +``` + +When unserializing without knowing the used symbols, our column name will actually be just symbol IDs `$`: + +```php +getBuffer(), [ + "multiSequence" => true, +])); + +/* +array(3) { + [0]=> + array(3) { + ["$10"]=> + int(1) + ["$11"]=> + string(3) "foo" + ["$12"]=> + bool(false) + } + [1]=> + array(3) { + ["$10"]=> + int(2) + ["$11"]=> + string(3) "bar" + ["$12"]=> + bool(true) + } + [2]=> + array(3) { + ["$10"]=> + int(3) + ["$11"]=> + string(3) "baz" + ["$12"]=> + bool(true) + } +} +*/ + +?> +``` + +When unserializing with known symbols, the symbol IDs will be resolved when using the catatalog with the appropriate symbol tables: + +```php +getBuffer(), [ + "multiSequence" => true, + "readerOptions" => [ + "catalog" => $catalog + ] +])); + +/* + array(3) { + [0]=> + array(3) { + ["id"]=> + int(1) + ["type"]=> + string(3) "foo" + ["state"]=> + bool(false) + } + [1]=> + array(3) { + ["id"]=> + int(2) + ["type"]=> + string(3) "bar" + ["state"]=> + bool(true) + } + [2]=> + array(3) { + ["id"]=> + int(3) + ["type"]=> + string(3) "baz" + ["state"]=> + bool(true) + } + } +*/ + +?> +``` + diff --git a/docs/v0.1/index.html b/docs/v0.1/index.html index 8d5effc..0a4c49e 100644 --- a/docs/v0.1/index.html +++ b/docs/v0.1/index.html @@ -47,7 +47,7 @@ See the Amazon ION specification. ion.stub.php
Last modified: - 2022-01-28 09:29:47 UTC + 2022-03-03 08:45:59 UTC diff --git a/docs/v0.1/ion.html b/docs/v0.1/ion.html index 8924ffa..b80a5c6 100644 --- a/docs/v0.1/ion.html +++ b/docs/v0.1/ion.html @@ -45,6 +45,11 @@ +
  • + ↳ ★ Tutorial + +
  • +
  • Catalog @@ -304,7 +309,7 @@ instances of the following PHP classes cannot be cloned:

      ion.stub.php
      Last modified: - 2022-01-28 09:29:47 UTC + 2022-03-03 08:45:59 UTC

    Functions: @@ -316,7 +321,7 @@ instances of the following PHP classes cannot be cloned:

    Serialize a PHP value as ION data.

    -

    string ion\serialize(mixed $data, [?ion\Serializer $serializer = NULL])

    +

    string ion\serialize(mixed $data, [ion\Serializer|array|null $serializer = NULL])

  • @@ -325,7 +330,7 @@ instances of the following PHP classes cannot be cloned:

    Namespaces, Interfaces and Classes: diff --git a/docs/v0.1/ion.stub.php b/docs/v0.1/ion.stub.php index 06eef69..9431b17 100644 --- a/docs/v0.1/ion.stub.php +++ b/docs/v0.1/ion.stub.php @@ -28,11 +28,11 @@ namespace ion; * * object (incl. \Serializable, and classes implementing magic and custom __serialize) * * @param mixed $data PHP value(s). - * @param Serializer|null $serializer Custom serializer. + * @param Serializer|array|null $serializer Custom serializer. * @return string serialized ION data * @throws \ion\Exception */ -function serialize(mixed $data, ?Serializer $serializer = null) : string {} +function serialize(mixed $data, Serializer|array|null $serializer = null) : string {} /** * Unserialize ION data (stream) as PHP value(s). @@ -41,7 +41,7 @@ function serialize(mixed $data, ?Serializer $serializer = null) : string {} * @return mixed unserialized PHP values * @throws \ion\Exception */ -function unserialize($data, ?Unserializer $unserializer = null) : mixed {} +function unserialize($data, Unserializer|array|null $unserializer = null) : mixed {} /** * Serializer interface, used to customize ion\serialize()'s behavior. @@ -275,13 +275,13 @@ class Timestamp extends \DateTime { * @param Timestamp\Precision|int $precision The timestamp's precision. * @param Timestamp\Format|string|null $format The timestamp's format. * @param string|null $datetime The timestamp's value. - * @param \DateTimeZone|null $timezone The timestamp's timezone. + * @param \DateTimeZone|string|null $timezone The timestamp's timezone. */ public function __construct( Timestamp\Precision|int $precision, Timestamp\Format|string|null $format = null, ?string $datetime = null, - ?\DateTimeZone $timezone = null, + \DateTimeZone|string|null $timezone = null, ) {} public function __toString() : string {} @@ -1055,7 +1055,7 @@ class PHP implements \ion\Serializer { /** * Writer options. */ - public readonly ?\ion\Writer\Options $writerOptions = null, + public readonly \ion\Writer\Options|array|null $writerOptions = null, /** * Whether to write the top level array as multiple ION sequences. */ @@ -1086,7 +1086,7 @@ class PHP implements \ion\Unserializer { /** * Reader options. */ - public readonly ?\ion\Reader\Options $readerOptions = null, + public readonly \ion\Reader\Options|array|null $readerOptions = null, /** * Whether to continue reading multiple ION sequences after the first one. */ diff --git a/docs/v0.1/ion/: Contributing.html b/docs/v0.1/ion/: Contributing.html index 0ee472f..f287245 100644 --- a/docs/v0.1/ion/: Contributing.html +++ b/docs/v0.1/ion/: Contributing.html @@ -44,6 +44,8 @@
  • ★ Security
  • +
  • ★ Tutorial
  • +
  • Catalog
  • Decimal
  • diff --git a/docs/v0.1/ion/: Security.html b/docs/v0.1/ion/: Security.html index c8e1513..984720c 100644 --- a/docs/v0.1/ion/: Security.html +++ b/docs/v0.1/ion/: Security.html @@ -44,6 +44,8 @@
  • ★ Contributing
  • +
  • ★ Tutorial
  • +
  • Catalog
  • Decimal
  • diff --git a/docs/v0.1/ion/: Tutorial.html b/docs/v0.1/ion/: Tutorial.html new file mode 100644 index 0000000..c30d701 --- /dev/null +++ b/docs/v0.1/ion/: Tutorial.html @@ -0,0 +1,166 @@ + + + + + + ★ Tutorial - + mdref + + + + + + + + + + +
    + + +

    +Tutorial

    Welcome to the ext-ion tutorial. We'll look into what Amazon's ION format is and how to use it from within PHP.

      +
    1. ★1. Getting started +
    2. +
    3. ★2. What is ion? +
    4. +
    5. ★3. Standard Datatypes +
    6. +
    7. ★4. Special Datatypes +
    8. +
    9. ★5. Symbols, Tables and Catalogs +
    10. +
    +

    Parts of this documentation are replicated verbatim of the official Amazon ION documentation licensed under the Apache 2.0 License.

    +
    
    +                                 Apache License
                               Version 2.0, January 2004
                            http://www.apache.org/licenses/

       TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

       1. Definitions.

          "License" shall mean the terms and conditions for use, reproduction,
          and distribution as defined by Sections 1 through 9 of this document.

          "Licensor" shall mean the copyright owner or entity authorized by
          the copyright owner that is granting the License.

          "Legal Entity" shall mean the union of the acting entity and all
          other entities that control, are controlled by, or are under common
          control with that entity. For the purposes of this definition,
          "control" means (i) the power, direct or indirect, to cause the
          direction or management of such entity, whether by contract or
          otherwise, or (ii) ownership of fifty percent (50%) or more of the
          outstanding shares, or (iii) beneficial ownership of such entity.

          "You" (or "Your") shall mean an individual or Legal Entity
          exercising permissions granted by this License.

          "Source" form shall mean the preferred form for making modifications,
          including but not limited to software source code, documentation
          source, and configuration files.

          "Object" form shall mean any form resulting from mechanical
          transformation or translation of a Source form, including but
          not limited to compiled object code, generated documentation,
          and conversions to other media types.

          "Work" shall mean the work of authorship, whether in Source or
          Object form, made available under the License, as indicated by a
          copyright notice that is included in or attached to the work
          (an example is provided in the Appendix below).

          "Derivative Works" shall mean any work, whether in Source or Object
          form, that is based on (or derived from) the Work and for which the
          editorial revisions, annotations, elaborations, or other modifications
          represent, as a whole, an original work of authorship. For the purposes
          of this License, Derivative Works shall not include works that remain
          separable from, or merely link (or bind by name) to the interfaces of,
          the Work and Derivative Works thereof.

          "Contribution" shall mean any work of authorship, including
          the original version of the Work and any modifications or additions
          to that Work or Derivative Works thereof, that is intentionally
          submitted to Licensor for inclusion in the Work by the copyright owner
          or by an individual or Legal Entity authorized to submit on behalf of
          the copyright owner. For the purposes of this definition, "submitted"
          means any form of electronic, verbal, or written communication sent
          to the Licensor or its representatives, including but not limited to
          communication on electronic mailing lists, source code control systems,
          and issue tracking systems that are managed by, or on behalf of, the
          Licensor for the purpose of discussing and improving the Work, but
          excluding communication that is conspicuously marked or otherwise
          designated in writing by the copyright owner as "Not a Contribution."

          "Contributor" shall mean Licensor and any individual or Legal Entity
          on behalf of whom a Contribution has been received by Licensor and
          subsequently incorporated within the Work.

       2. Grant of Copyright License. Subject to the terms and conditions of
          this License, each Contributor hereby grants to You a perpetual,
          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
          copyright license to reproduce, prepare Derivative Works of,
          publicly display, publicly perform, sublicense, and distribute the
          Work and such Derivative Works in Source or Object form.

       3. Grant of Patent License. Subject to the terms and conditions of
          this License, each Contributor hereby grants to You a perpetual,
          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
          (except as stated in this section) patent license to make, have made,
          use, offer to sell, sell, import, and otherwise transfer the Work,
          where such license applies only to those patent claims licensable
          by such Contributor that are necessarily infringed by their
          Contribution(s) alone or by combination of their Contribution(s)
          with the Work to which such Contribution(s) was submitted. If You
          institute patent litigation against any entity (including a
          cross-claim or counterclaim in a lawsuit) alleging that the Work
          or a Contribution incorporated within the Work constitutes direct
          or contributory patent infringement, then any patent licenses
          granted to You under this License for that Work shall terminate
          as of the date such litigation is filed.

       4. Redistribution. You may reproduce and distribute copies of the
          Work or Derivative Works thereof in any medium, with or without
          modifications, and in Source or Object form, provided that You
          meet the following conditions:

          (a) You must give any other recipients of the Work or
              Derivative Works a copy of this License; and

          (b) You must cause any modified files to carry prominent notices
              stating that You changed the files; and

          (c) You must retain, in the Source form of any Derivative Works
              that You distribute, all copyright, patent, trademark, and
              attribution notices from the Source form of the Work,
              excluding those notices that do not pertain to any part of
              the Derivative Works; and

          (d) If the Work includes a "NOTICE" text file as part of its
              distribution, then any Derivative Works that You distribute must
              include a readable copy of the attribution notices contained
              within such NOTICE file, excluding those notices that do not
              pertain to any part of the Derivative Works, in at least one
              of the following places: within a NOTICE text file distributed
              as part of the Derivative Works; within the Source form or
              documentation, if provided along with the Derivative Works; or,
              within a display generated by the Derivative Works, if and
              wherever such third-party notices normally appear. The contents
              of the NOTICE file are for informational purposes only and
              do not modify the License. You may add Your own attribution
              notices within Derivative Works that You distribute, alongside
              or as an addendum to the NOTICE text from the Work, provided
              that such additional attribution notices cannot be construed
              as modifying the License.

          You may add Your own copyright statement to Your modifications and
          may provide additional or different license terms and conditions
          for use, reproduction, or distribution of Your modifications, or
          for any such Derivative Works as a whole, provided Your use,
          reproduction, and distribution of the Work otherwise complies with
          the conditions stated in this License.

       5. Submission of Contributions. Unless You explicitly state otherwise,
          any Contribution intentionally submitted for inclusion in the Work
          by You to the Licensor shall be under the terms and conditions of
          this License, without any additional terms or conditions.
          Notwithstanding the above, nothing herein shall supersede or modify
          the terms of any separate license agreement you may have executed
          with Licensor regarding such Contributions.

       6. Trademarks. This License does not grant permission to use the trade
          names, trademarks, service marks, or product names of the Licensor,
          except as required for reasonable and customary use in describing the
          origin of the Work and reproducing the content of the NOTICE file.

       7. Disclaimer of Warranty. Unless required by applicable law or
          agreed to in writing, Licensor provides the Work (and each
          Contributor provides its Contributions) on an "AS IS" BASIS,
          WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
          implied, including, without limitation, any warranties or conditions
          of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
          PARTICULAR PURPOSE. You are solely responsible for determining the
          appropriateness of using or redistributing the Work and assume any
          risks associated with Your exercise of permissions under this License.

       8. Limitation of Liability. In no event and under no legal theory,
          whether in tort (including negligence), contract, or otherwise,
          unless required by applicable law (such as deliberate and grossly
          negligent acts) or agreed to in writing, shall any Contributor be
          liable to You for damages, including any direct, indirect, special,
          incidental, or consequential damages of any character arising as a
          result of this License or out of the use or inability to use the
          Work (including but not limited to damages for loss of goodwill,
          work stoppage, computer failure or malfunction, or any and all
          other commercial damages or losses), even if such Contributor
          has been advised of the possibility of such damages.

       9. Accepting Warranty or Additional Liability. While redistributing
          the Work or Derivative Works thereof, You may choose to offer,
          and charge a fee for, acceptance of support, warranty, indemnity,
          or other liability obligations and/or rights consistent with this
          License. However, in accepting such obligations, You may act only
          on Your own behalf and on Your sole responsibility, not on behalf
          of any other Contributor, and only if You agree to indemnify,
          defend, and hold each Contributor harmless for any liability
          incurred by, or claims asserted against, such Contributor by reason
          of your accepting any such warranty or additional liability.

       END OF TERMS AND CONDITIONS
    +
    +
    + + + + +
    + + + + + +
    + + diff --git a/docs/v0.1/ion/: Tutorial/:1. Getting started.html b/docs/v0.1/ion/: Tutorial/:1. Getting started.html new file mode 100644 index 0000000..995d952 --- /dev/null +++ b/docs/v0.1/ion/: Tutorial/:1. Getting started.html @@ -0,0 +1,147 @@ + + + + + + ★1. Getting started - + mdref + + + + + + + + + + +
    + + +

    +Getting started

    The PHP extension for Ion requires PHP version 8.1 or greater, see the Install section.

    Why Ion? +

      +
    • Ion provides dual-format interoperability, which enables users to take advantage of the ease of use of the text format while capitalizing on the efficiency of the binary format. The text form is easy to prototype, test, and debug, while the binary format saves space and parsing effort.
    • +
    • Ion’s rich type system extends JSON’s, adding support for types that make Ion suitable for a wider variety of uses, including precision-sensitive applications and portability across languages and runtimes.
    • +
    • Ion is a self-describing format, giving its readers and writers the flexibility to exchange Ion data without needing to agree on a schema in advance. Ion’s “open-content” supports discovery, deep component chaining, and schema evolution.
    • +
    • Because most data is read more often than it is written, Ion defines a read-optimized binary format.
    • +

    Dual-format interoperability +

    Applications can seamlessly consume Ion data in either its text or binary forms without loss of data fidelity. While the expectation is that most Ion data is in binary form, the text form promotes human readability, simplifying discovery and diagnosis.

    Notably, the text format is a superset of JSON, making all JSON data valid Ion data. You probably already know how to read and author Ion.

    Ease of use +

    Like JSON, Ion’s text format is concise and clearly legible. It is intelligible to humans and may be edited using familiar tools like a text editor. This makes Ion well-suited to rapid prototyping: developers can quickly mock up the their data in text Ion, knowing that their application will ultimately seamlessly process the more efficient binary Ion format. Once the application is up and running, the users can debug it by intercepting the binary Ion data and converting it to text Ion with full fidelity. After analysis, hand-edited records can be re-inserted into a processing pipeline as needed to support debugging and prototyping.

    Text-only formats are more expensive to parse, which is why Ion offers the option of the length-prefixed binary format. This binary format supports rapid skip-scanning of data to materialize only key values within Ion streams.

    Seamless transcoding +

    Ion’s interoperable formats avoid the kinds of semantic mismatches encountered when attempting to mix and match separate text and binary formats.

    Standalone binary formats such as CBOR sacrifice human-readability in favor of an encoding that is more compact and efficient to parse. Although CBOR is based on JSON, transcoding between the two is not always straightforward because CBOR’s more expressive types do not necessarily map cleanly to JSON types. For example, CBOR’s bignum must be base-64 encoded and represented as a JSON string in order to avoid numeric overflow when read by a JSON parser, while a CBOR map may be directly converted to a JSON object only if all its keys are UTF-8 strings.

    Rich type system +

    Ion’s type system is a superset of JSON’s: in addition to strings, booleans, arrays (lists), objects (structs), and nulls, Ion adds support for arbitrary-precision timestamps, embedded binary values (blobs and clobs), and symbolic expressions. Ion also expands JSON’s number specification by defining distinct types for arbitrary-size integers, IEEE-754 binary floating point numbers, and infinite-precision decimals. Decimals are particularly useful for precision-sensitive applications such as financial transaction record-keeping. JSON’s number type is underspecified; in practice, many implementations represent all JSON numbers as fixed-precision base-2 floats, which are subject to rounding errors and other loss of precision.

    Timestamps +

    Ion timestamps are W3C-compliant representations of calendar dates and time, supporting variable precision including year, month, day, hours, minutes, seconds, and fractional seconds. Ion timestamps may optionally encode a time zone offset.

    By defining timestamps as a distinct type, Ion eliminated the ambiguity involved with representing dates as strings, as the semantics are clearly defined. Unlike a number, which counts from some “epoch”, arbitrary precision timestamps also allow applications to represent deliberate ambiguity.

    Blobs and Clobs +

    Ion’s blob and clob types allow applications to tunnel binary data through Ion. This allows such applications to transmit opaque binary payloads (e.g. media, code, and non-UTF-8 text) in Ion without the need to apply additional processing to the payloads to make them conform to a different Ion type.

    For example, a blob could be used to transmit a bitmap image, while a clob could be used to transmit Shift JIS text or an XML payload.

    Symbolic expressions +

    The Ion specification defines a distinct syntax for symbolic expressions (S-expressions), but does not define how they should be processed. This allows applications to use S-expressions to convey domain-specific semantics in a first-class Ion type.

    Formats that lack S-expressions as a first-class type are often left to choose between two imperfect options: adding a pre-processor (e.g. Jsonnet on top of JSON) to work around the inability to represent expressions as data, or tunneling domain-specific language text as opaque strings or binary payloads.

    Annotations +

    The Ion specification provides a formal mechanism for applications to annotate any Ion value without the need to enclose the value in a container. These annotations are not interpreted by Ion readers and may be used, for example, to add type information to a struct, time units to an integer or decimal value, or a description of the contents of a blob value.

    Self-describing +

    Like JSON and CBOR, Ion is a self-describing format, meaning that it does not require external metadata (i.e. a schema) in order to interpret the structural characteristics of data denoted by the format. Notably, Ion payloads are free from build-time binding that inhibits independent innovation and evolution across service boundaries. This provides greater flexibility over schema-based formats such as protocol buffers, Thrift, and Avro, as data may be sparsely encoded and the implicit schema may be changed without explicit renegotiation of the schema among all consumers. These benefits come at the cost of a less compact encoding, but in our experience the positive impact on agility has been more valuable than an efficient but brittle contract.

    Read-optimized binary format +

    Ion’s binary format is optimized according to the following principles:

      +
    • Most data is read far more often than it is written. Generally, with the exception of logs, any data which is written is read at least once. Read multipliers are common in processing pipelines, workflows, and shared data marts.
    • +
    • Many reads are shallow or sparse, meaning that the application is focused on only a subset of the values in the stream, and that it can quickly determine if full materialization of a value is required.
    • +

    In the spirit of these principles, the Ion specification includes features that make Ion’s binary encoding more efficient to read than other schema-free formats. These features include length-prefixing of binary values and Ion’s use of symbol tables.

    Length-prefixing +

    Because most reads are sparse, binary Ion invests some encoding space to length-prefix each value in a stream. This makes seeking to the next relevant value for a particular application inexpensive, and enables efficient skip-scanning of data. This allows applications to cherry-pick only the relevant values from the stream for deeper parsing, and to economize parsing of irrelevant values.

    Symbol tables +

    In binary Ion, common text tokens such as struct field names are automatically stored in a symbol table. This allows these tokens to be efficiently encoded as table offsets instead of repeated copies of the same text. As a further space optimization, symbol tables can be pre-shared between producer and consumer so that only the table name and version are included in the payload, eliminating the overhead involved with repeatedly defining the same symbols across multiple pieces of Ion data.

    Install +

    You can get started installing ext-ion the usual ways:

    PECL +

    pecl install ion

    Trinity +

    
    +./configure
    make #-j$(nproc)
    sudo make install #INSTALL=install
    +

    PHARext +

    See https://pharext.org and https://replicator.pharext.org/?ion

    Quick: +

    
    +curl -sSO https://replicator.pharext.org/phars/ion/ion-0.1.0.ext.phar
    php ./ion-0.1.0.ext.phar --sudo --ini <path/to/pecl.ini>
    +

    Verified: +

    
    +# download phar, signature and public key
    curl -sSO https://replicator.pharext.org/replicator.pub
    curl -sSO https://replicator.pharext.org/phars/ion/ion-0.1.0.ext.phar
    curl -sSO https://replicator.pharext.org/sigs/ion/ion-0.1.0.ext.phar.sig

    # verify signature against public key
    openssl dgst \
      -verify    replicator.pub \
      -signature ion-0.1.0.ext.phar.sig \
                 ion-0.1.0.ext.phar

    # install verified extension
    php ./ion-0.1.0.ext.phar --sudo --ini <path/to/pecl.ini>

    +

    Check +

    php -m | grep ^ion should show: ion.


    Next up +

    +
    + + + + +
    + + + + + +
    + + diff --git a/docs/v0.1/ion/: Tutorial/:2. What is ion.html b/docs/v0.1/ion/: Tutorial/:2. What is ion.html new file mode 100644 index 0000000..60ec895 --- /dev/null +++ b/docs/v0.1/ion/: Tutorial/:2. What is ion.html @@ -0,0 +1,163 @@ + + + + + + ★2. What is ion - + mdref + + + + + + + + + + +
    + + +

    +What Is Ion?

    Quoting the official Ion documentation:

    Amazon Ion is a richly-typed, self-describing, hierarchical data serialization format offering interchangeable binary and text representations. The text format (a superset of JSON) is easy to read and author, supporting rapid prototyping.

    The binary representation is efficient to store, transmit, and skip-scan parse.

    The rich type system provides unambiguous semantics for longterm preservation of data which can survive multiple generations of software evolution.

    Ion was built to address rapid development, decoupling, and efficiency challenges faced every day while engineering large-scale, service-oriented architectures.

    Some simple examples +

    Serialization: +

    
    +<?=
    ion\serialize
    ([
      
    "key" => "value",
      
    "more" => [
        
    "data" => 123
      
    ]
    ]);
    ?>
    +
    +
    Output: +
    
    +{key:"value",more:{data:123}}
    +

    If you now think that this looks a lot like JSON, you're probably right, because Ion is a superset of JSON:

    
    +<?=
    json_encode
    ([
      
    "key" => "value",
      
    "more" => [
        
    "data" => 123
      
    ]
    ]);
    ?>
    +
    +
    Output: +
    
    +{"key":"value","more":{"data":123}}
    +

    So, all valid JSON is also valid Ion. Please refer to the official spec to learn more about this topic.

    Unserialization: +

    
    +<?=
    var_representation
    (
      
    ion\unserialize('{key:"value",more:{data:123}}')
    );
    ?>
    +
    +
    Output: +
    
    +[
      'key' => 'value',
      'more' => [
        'data' => 123,
      ],
    ]
    +

    If you try the same with the JSON equivalent, you'll see that it's basically valid Ion, too:

    
    +<?=
    var_representation
    (
      
    ion\unserialize('{"key":"value","more":{"data":123}}')
    );
    ?>
    +
    +
    Output: +
    
    +[
      'key' => 'value',
      'more' => [
        'data' => 123,
      ],
    ]
    +

    Multiple documents +

    Ion supports multiple sequences of documents within a single stream; consider the following:

    
    +<?=
    var_representation
    (
      
    ion\unserialize('
        {"key":"value","more":{"data":123}}
        {"key":"value","more":{"data":456}}
      '
    , new ion\Unserializer\PHP(multiSequence: true)
      )
    );
    ?>
    +
    +

    Output: +

    
    +[
      [
        'key' => 'value',
        'more' => [
          'data' => 123,
        ],
      ],
      [
        'key' => 'value',
        'more' => [
          'data' => 456,
        ],
      ],
    ]
    +

    Annotations +

    Any Ion value can include one or more annotation symbols denoting the semantics of the content. This can be used to:

      +
    • Annotate individual values with schema types, for validation purposes.
    • +
    • Associate a higher-level datatype (e.g. a Java class) during serialization processes.
    • +
    • Indicate the notation used within a blob or clob value.
    • +
    • Apply other application semantics to a single value.
    • +

    In the text format, type annotations are denoted by a non-null symbol token and double-colons preceding any value. Multiple annotations on the same value are separated by double-colons:

    
    +int32::12                                // Suggests 32 bits as end-user type
    degrees::'celsius'::100                  // You can have multiple annotaions on a value
    'my.custom.type' :: { x : 12 , y : -1 }  // Gives a struct a user-defined type

    { field: some_annotation::value }        // Field's name must precede annotations of its value

    jpeg :: {{ ... }}                        // Indicates the blob contains jpeg data
    bool :: null.int                         // A very misleading annotation on the integer null
    '' :: 1                                  // An empty annotation
    null.symbol :: 1                         // ERROR: type annotation cannot be null 
    +

    Except for a small number of predefined system and PHP annotations, Ion itself neither defines nor validates such annotations; that behavior is left to applications or tools (such as schema validators).

    It’s important to understand that annotations are symbol tokens, not symbol values. That means they do not have annotations themselves. In particular, the text a::c is a single value consisting of three textual tokens (a symbol, a double-colon, and another symbol); the first symbol token is an annotation on the value, and the second is the content of the value.

    System Annotations +

    
    +<?php

    foreach (ion\Symbol\System::cases() as $e) {
      
    printf("%30s:: => %s\n", $e->value, $e->name);
    }

    /*
                              $ion:: => Ion
                          $ion_1_0:: => Ivm_1_0
                 $ion_symbol_table:: => IonSymbolTable
                              name:: => Name
                           version:: => Version
                           imports:: => Imports
                           symbols:: => Symbols
                            max_id:: => MaxId
          $ion_shared_symbol_table:: => SharedSymbolTable
    */

    ?>
    +
    +

    PHP Annotations +

    There are two handful of annotations used by PHP, which are centralized in the ion\Symbol\PHP enumeration:

    
    +<?php

    foreach (ion\Symbol\PHP::cases() as $e) {
      
    printf("%3s:: => %s\n", $e->value, $e->name);
    }

    /*
      PHP:: => PHP
        R:: => Reference
        r:: => Backref
        p:: => Property
        o:: => Object
        c:: => ClassObject
        O:: => MagicObject
        C:: => CustomObject
        E:: => Enum
        S:: => Serializable
    */

    ?>
    +
    +

    Next up +

    +
    + + + + +
    + + + + + +
    + + diff --git a/docs/v0.1/ion/: Tutorial/:2. What is ion?.html b/docs/v0.1/ion/: Tutorial/:2. What is ion?.html new file mode 100644 index 0000000..5ef5a08 --- /dev/null +++ b/docs/v0.1/ion/: Tutorial/:2. What is ion?.html @@ -0,0 +1,131 @@ + + + + + + ★2. What is ion - + mdref + + + + + + + + + + +
    + + +

    What Is Ion? +

    Quoting the official Ion documentation:

    +

    Amazon Ion is a richly-typed, self-describing, hierarchical data serialization format offering interchangeable binary and text representations. The text format (a superset of JSON) is easy to read and author, supporting rapid prototyping. The binary representation is efficient to store, transmit, and skip-scan parse. The rich type system provides unambiguous semantics for long-term preservation of data which can survive multiple generations of software evolution.

    +

    Ion was built to address rapid development, decoupling, and efficiency challenges faced every day while engineering large-scale, service-oriented architectures. It has been addressing these challenges within Amazon for nearly a decade, and we believe others will benefit as well.

    +

    Simple serialization +

    
    +<?php
    echo ion\serialize([
      
    "key" => "value",
      
    "more" => [
        
    "data" => 123
      
    ]
    ]);
    ?>
    +
    +

    Output: +

    
    +{key:"value",more:{data:123}}
    +

    If you now think that this looks a lot like JSON, you're probably right, because Ion is a superset of JSON:

    
    +<?php
    echo json_encode([
      
    "key" => "value",
      
    "more" => [
        
    "data" => 123
      
    ]
    ]);
    ?>
    +
    +

    Output: +

    
    +{"key":"value","more":{"data":123}}
    +

    So, all valid JSON is also valid Ion. Please refer to the official spec to learn more about this topic.

    Simple unserialization +

    
    +<?=
    var_representation
    (
      
    ion\unserialize('{key:"value",more:{data:123}}')
    );
    ?>
    +
    +

    Output: +

    
    +[
      'key' => 'value',
      'more' => [
        'data' => 123,
      ],
    ]
    +

    If you try the same with the JSON equivalent, you'll see that it's basically valid Ion, too:

    
    +<?=
    var_representation
    (
      
    ion\unserialize('{"key":"value","more":{"data":123}}')
    );
    ?>
    +
    +

    Output: +

    
    +[
      'key' => 'value',
      'more' => [
        'data' => 123,
      ],
    ]
    +

    +
    + + + + +
    + + + + + +
    + + diff --git a/docs/v0.1/ion/: Tutorial/:3. Datatypes.html b/docs/v0.1/ion/: Tutorial/:3. Datatypes.html new file mode 100644 index 0000000..591ad5d --- /dev/null +++ b/docs/v0.1/ion/: Tutorial/:3. Datatypes.html @@ -0,0 +1,161 @@ + + + + + + ★3. Datatypes - + mdref + + + + + + + + + + +
    + + +

    +Datatypes

    Standard datatypes +

    ION supports many of PHP's data types:

    +NULL +

    Additonally to the plain and simple NULL, ION can attach a type to NULL values.

    
    +<?php
      
    $writer 
    = new ion\Writer\Stream\Writer(STDOUT);
    $writer->writeNull();
    $writer->writeTypedNull(ion\Type::Int);
    $writer->writeTypedNull(ion\Type::String);
    $writer->flush();

    /*
        null null.int null.string
    */

    ?>
    +
    +

    Special datatypes +

    There are a handful of data types treated in a specific way in PHP; consider the following examples:

    Deprecated Serializable +

    +

    NOTE:
    +The interface Serializable has been deprecated in 8.1 and should be replaced with magic serialize methods.

    +
    
    +<?php
      
    class srlzbl implements \Serializable {
      private 
    $data = "foo";
      public function 
    serialize() { 
        return 
    "bar"; 
      }
      public function 
    unserialize($data) { 
        
    $this->data = $data; 
      }
    }

    $srlzbl = new srlzbl;
    var_dump($srlzbl);

    $srlzd = ion\serialize($srlzbl);
    echo 
    $srlzd;

    /*
        object(srlzbl)#4 (1) {
            ["data":"srlzbl":private]=>
            string(3) "foo"
        }
        
        S::srlzbl::{{"bar"}}

    */

    ?>
    +
    +

    Everything as expected so far, Serializable return a string, but since it cannot indicate whether it's a valid UTF-8 string, a ion\Type::CLob or ion\Type::BLob, CLobs are assumed.

    Unserialization does not offer any surprises, either:

    
    +<?php 
      
    var_dump
    (ion\unserialize($srlzd));

    /*
      object(srlzbl)#4 (1) {
        ["data":"srlzbl":private]=>
        string(3) "bar"
      }

    */

    ?>
    +
    +

    Magic __serialize +

    Implementing serialization behavior with magic methods is the preferred way since 8.1:

    
    +<?php
      
    class magic {
      private 
    string $foo = "foo";
      function 
    __serialize() : array {
        return [
    "foo" => "bar"];
      }
      function 
    __unserialize(array $data) : void {
        foreach (
    $data as $k => $v) 
          
    $this->$k = $v;
      }
    }

    $magic = new magic;
    var_dump($magic);

    $srlzd = ion\serialize($magic);
    echo 
    $srlzd;

    /*
      object(magic)#6 (1) {
        ["foo":"magic":private]=>
        string(3) "foo"
      }

      O::magic::{foo:"bar"}

    */

    ?>
    +
    +

    Again, unserialization yields the expected results:

    
    +<?php
      
    var_dump
    (ion\unserialize($srlzd));

    /*
      object(magic)#7 (1) {
        ["foo":"magic":private]=>
        string(3) "bar"
      }

    */

    ?>
    +
    +

    Custom serialize +

    Customly serializable objects work like magic serializable objects, with custom names for the magic methods.

    
    +<?php
      
    class custom {
      private array 
    $data;
      function 
    init(array $data) : void {
        
    $this->data = $data;
      }
      function 
    export() : array {
        return 
    $this->data;
      }
    }

    $custom = new custom;
    $custom->init(["foo" => "bar"]);
    echo 
    $srlzd = ion\serialize($custom);

    /*
        c::custom::{data:p::custom::{foo:"bar"}}
        
    */

    ?>
    +
    +

    The above is actually the result of serializing a plain old PHP object, because we didn't implement any serialization primitives and did neither specify a custom method to call. So let's just do that:

    
    +<?php
      
    $srlzr 
    = new ion\Serializer\PHP(callCustomSerialize: "export");
    echo 
    $srlzd = ion\serialize($custom, $srlzr);

    /*
        C::custom::{foo:"bar"}

    */

    ?>
    +
    +

    Note how this output compares to the output of the standard magic serializable object.

    Unserialization works as used to, except sepcifying thwe custom unserialization method to call:

    
    +<?php
      
    $unsrlzr 
    = new ion\Unserializer\PHP(callCustomUnserialize: "init");
    var_dump(ion\unserialize($srlzd, $unsrlzr));

    /*
        object(custom)#10 (1) {
        ["data":"custom":private]=>
        array(1) {
          ["foo"]=>
          string(3) "bar"
        }
      }

    */

    ?>
    +
    +

    Decimal +

    LOB +

    Symbol +

    Timestamp +

    Instances of ion\Timestamp are really just plain \DateTime objects augmented with Stringable and ION specific formatting.

    
    +<?=
    new ion\Timestamp(
        
    precision: ion\Timestamp\Precision::FracTZ,
    ) 
      
      
    // 2022-02-25T16:11:54.118+00:00
      
    ?>
    +
    +
    
    +<?=
    new ion\Timestamp(
        
    precision: ion\Timestamp\Precision::Day
    ) 
      
      
    // 2022-02-25T
      
    ?>
    +
    +
    
    +<?=
    new ion\Timestamp(
      
    precision: ion\Timestamp\Precision::MinTZ,
      
    format: ion\Timestamp\Format::Min,
      
    datetime: "2020-03-15T12:34",
      
    timezone: new DateTimeZone("Europe/Vienna")
    ) 
      
      
    // 2020-03-15T12:34+01:00
      
    ?>
    +
    +
    +
    + + + + +
    + + + + + +
    + + diff --git a/docs/v0.1/ion/: Tutorial/:3. Standard Datatypes.html b/docs/v0.1/ion/: Tutorial/:3. Standard Datatypes.html new file mode 100644 index 0000000..557c374 --- /dev/null +++ b/docs/v0.1/ion/: Tutorial/:3. Standard Datatypes.html @@ -0,0 +1,160 @@ + + + + + + ★3. Standard Datatypes - + mdref + + + + + + + + + + +
    + + +

    +Standard Datatypes

    ION supports many of PHP's data types:

    Nulls +

    Additonally to the plain and simple NULL, ION can attach a type to NULL values.

    
    +<?php
      
    $writer 
    = new ion\Writer\Stream\Writer(STDOUT);
    $writer->writeNull();
    $writer->writeTypedNull(ion\Type::Int);
    $writer->writeTypedNull(ion\Type::String);
    $writer->flush();

    /*
        null
        null.int
        null.string
    */

    ?>
    +
    +

    Booleans +

    The bool type does not need a lot of explanation:

    
    +<?php

    $writer
    ->writeBool(true);
    $writer->writeBool(false);
    $writer->flush();

    /*
        true
        false
    */

    ?>
    +
    +

    Integers +

    The int type comprises signed integers of arbitrary size.

    
    +<?php
      
    $writer
    ->writeInt(123);
    $writer->writeInt("12345678901234567890");
    $writer->flush();

    /*
        123
        12345678901234567890
    */

    ?>
    +
    +

    In ION-Text, underscores are allowed to separate digits:

    
    +<?php
      
    $reader 
    = new ion\Reader\Buffer\Reader("-123_456_789");
    $reader->next();
    var_dump($reader->getType());
    var_dump($reader->readInt());

    /*
        enum(ion\Type::Int)
        int(-123456789)
    */

    ?>
    +
    +

    Hexadecimal as well as binary notation are supported, too:

    
    +<?php

    $reader 
    = new ion\Reader\Buffer\Reader("0xdead_beef");
    $reader->next();
    var_dump($reader->readInt());

    /*
        int(3735928559)
    */

    $reader = new ion\Reader\Buffer\Reader("0b10000100_11001001");
    $reader->next();
    var_dump($reader->readInt());

    /*
        int(33993)
    */

    ?>
    +
    +

    Reals +

    Ion supports both binary and lossless decimal encodings of real numbers as, respectively, types float and decimal. In the text format, float values are denoted much like the decimal formats in C or Java; decimal values use d instead of e to start the exponent.

    Reals without an exponent are treated as decimal. As with JSON, extra leading zeros are not allowed. Digits may be separated with an underscore.

    Floats +

    
    +<?php

    var_dump
    (ion\serialize(0.123));

    /*
        string(25) "0.12299999999999999822e+0"
    */

    var_dump(ion\unserialize("[0.123e, 123e-3]"));

    /*
      array(2) {
        [0]=>
        float(0.123)
        [1]=>
        float(0.123)
      }
    */

    ?>
    +
    +

    Decimals +

    
    +<?php

    var_dump
    (ion\serialize(new ion\Decimal("0.123")));

    /*
        string(5) "0.123"
    */

    var_dump(ion\unserialize("[0.123d0, 123d-3]"));

    /*
      array(2) {
        [0]=>
        object(ion\Decimal)#8 (2) {
          ["number"]=>
          string(5) "0.123"
          // ...
        }
        [1]=>
        object(ion\Decimal)#11 (2) {
          ["number"]=>
          string(5) "0.123"
          // ...
        }
      }
    */

    ?>
    +
    +

    Strings +

    Ion strings are Unicode character sequences of arbitrary length.

    In the text format, strings are delimited by double-quotes and follow common backslash-escape conventions (see official spec). The binary format always uses UTF-8 encoding.

    
    +<?=

    ion\serialize
    ([
      
    "abc", "new
    line"
    ]);

    /*
        ["abc", "new\nline"]
    */

    ?>
    +
    +

    Long Strings +

    The text format supports an alternate syntax for “long strings”, including those that break across lines. Sequences bounded by three single-quotes (''') can cross multiple lines and still count as a valid, single string. In addition, any number of adjacent triple-quoted strings are concatenated into a single value.

    The concatenation happens within the Ion text parser and is neither detectable via the data model nor applicable to the binary format. Note that comments are always treated as whitespace, so concatenation still occurs when a comment falls between two long strings.

    
    +<?php
      
    var_dump
    (ion\unserialize("
    '''
      here are 
      several new
      lines
    '''
    "
    ));

    /*
    string(35) "
      here are 
      several new
      lines
    "
    */

    ?>
    +
    +

    Containers +

    Ion defines three container types: structures, lists, and S-expressions. These types are defined recursively and may contain values of any Ion type.

    Lists +

    Lists are ordered collections of values. The contents of the list are heterogeneous (that is, each element can have a different type). In the text format, lists are bounded by square brackets and elements are separated by commas.

    
    +<?=

    ion\serialize
    ([1, "yes", null]);

    /*
      [1,"yes",null]
    */

    ?>
    +
    +

    Structures +

    Structures are unordered collections of name/value pairs. The names are symbol tokens, and the values are unrestricted. Each name/value pair is called a field.

    In the text format, structures are wrapped by curly braces, with a colon between each name and value, and a comma between the fields. For the purposes of JSON compatibility, it’s also legal to use strings for field names, but they are converted to symbol tokens by the parser.

    
    +<?=

    ion\serialize
    ([
      
    "outlaw",
      
    "key" => "value",
      
    "obj" => (object)["key" => "value"]
    ]);

    /*
        {'0':"outlaw",key:"value",obj:o::{key:"value"}}
    */

    ?>
    +
    +
    
    +<?php

    var_dump
    (ion\unserialize(
      
    '{\'0\':"outlaw",key:"value",obj:o::{key:"value"}}'
    ));

    /*
      array(3) {
        [0]=>
        string(6) "outlaw"
        ["key"]=>
        string(5) "value"
        ["obj"]=>
        object(stdClass)#10 (1) {
          ["key"]=>
          string(5) "value"
        }
      }
    */

    ?>
    +
    +

    Next up +

    +
    + + + + +
    + + + + + +
    + + diff --git a/docs/v0.1/ion/: Tutorial/:4. Special Datatypes.html b/docs/v0.1/ion/: Tutorial/:4. Special Datatypes.html new file mode 100644 index 0000000..59524ca --- /dev/null +++ b/docs/v0.1/ion/: Tutorial/:4. Special Datatypes.html @@ -0,0 +1,166 @@ + + + + + + ★4. Special Datatypes - + mdref + + + + + + + + + + +
    + + +

    +Special Datatypes

    There are a handful of data types treated in a specific way in PHP; consider the following examples:

    Symbols +

    Symbols are much like strings, in that they are Unicode character sequences. The primary difference is the intended semantics: symbols represent semantic identifiers as opposed to textual literal values. Symbols are case sensitive.

    In the text format, symbols are delimited by single-quotes and use the same escape characters.

    See Ion Symbols for more details about symbol representations and symbol tables, and our section on Symbols, Tables and Catalogs for a distilled read.

    Decimals +

    See the section on reals for an introduction.

    
    +<?php
    $d 
    = new ion\Decimal(123);
    echo 
    ion\serialize($d), " = ", $d->isInt() ? "int" : "noint", "\n";
    // 123d0 = int

    $d = new ion\Decimal("123.123");
    echo 
    ion\serialize($d), " = ", $d->isInt() ? "int" : "noint" ,"\n";
    // 123.123 = noint

    ?>
    +
    +

    See the official ION spec about real numbers and also Ion Float and Ion Decimals for more notes.

    LOBs +

    BLob +

    The blob type allows embedding of arbitrary raw binary data. Ion treats such data as a single (though often very large) value. It does no processing of such data other than passing it through intact.

    In the text format, blob values are denoted as RFC 4648-compliant Base64 text within two pairs of curly braces.

    
    +{{ dHdvIHBhZGRpbmcgY2hhcmFjdGVycw== }}
    +

    CLob +

    The clob type is similar to blob in that it holds uninterpreted binary data. The difference is that the content is expected to be text, so we use a text notation that’s more readable than Base64.

    
    +{{ "This is a CLOB of text." }}
    +

    See the official ION specification on Blobs and Clobs.

    Timestamps +

    Timestamps represent a specific moment in time, always include a local offset, and are capable of arbitrary precision.

    Instances of ion\Timestamp are really just plain \DateTime objects augmented with Stringable and ION specific formatting.

    
    +<?=
    new ion\Timestamp(
        
    precision: ion\Timestamp\Precision::FracTZ,
    ) 
      
      
    // 2022-02-25T16:11:54.118+00:00
      
    ?>
    +
    +
    
    +<?=
    new ion\Timestamp(
        
    precision: ion\Timestamp\Precision::Day
    ) 
      
      
    // 2022-02-25T
      
    ?>
    +
    +
    
    +<?=
    new ion\Timestamp(
      
    precision: ion\Timestamp\Precision::MinTZ,
      
    format: ion\Timestamp\Format::Min,
      
    datetime: "2020-03-15T12:34",
      
    timezone: new DateTimeZone("Europe/Vienna")
    ) 
      
      
    // 2020-03-15T12:34+01:00
      
    ?>
    +
    +

    See also the official ION Timestamp specification.

    Special PHP Objects +

    Deprecated Serializable: +

    +

    NOTE:
    +The interface Serializable has been deprecated in 8.1 and should be replaced with magic serialize methods.

    +
    
    +<?php
      
    class srlzbl implements \Serializable {
      private 
    $data = "foo";
      public function 
    serialize() { 
        return 
    "bar"; 
      }
      public function 
    unserialize($data) { 
        
    $this->data = $data; 
      }
    }

    $srlzbl = new srlzbl;
    var_dump($srlzbl);

    $srlzd = ion\serialize($srlzbl);
    echo 
    $srlzd;

    /*
        object(srlzbl)#4 (1) {
            ["data":"srlzbl":private]=>
            string(3) "foo"
        }
        
        S::srlzbl::{{"bar"}}

    */

    ?>
    +
    +

    Everything as expected so far, Serializable return a string, but since they cannot indicate whether it's a valid UTF-8 string, a ion\Type::CLob or ion\Type::BLob, CLobs are assumed.

    Unserialization does not offer any surprises, either:

    
    +<?php 
      
    var_dump
    (ion\unserialize($srlzd));

    /*
      object(srlzbl)#4 (1) {
        ["data":"srlzbl":private]=>
        string(3) "bar"
      }

    */

    ?>
    +
    +

    Magic __serialize: +

    Implementing serialization behavior with magic methods is the preferred way since 8.1:

    
    +<?php
      
    class magic {
      private 
    string $foo = "foo";
      function 
    __serialize() : array {
        return [
    "foo" => "bar"];
      }
      function 
    __unserialize(array $data) : void {
        foreach (
    $data as $k => $v) 
          
    $this->$k = $v;
      }
    }

    $magic = new magic;
    var_dump($magic);

    $srlzd = ion\serialize($magic);
    echo 
    $srlzd;

    /*
      object(magic)#6 (1) {
        ["foo":"magic":private]=>
        string(3) "foo"
      }

      O::magic::{foo:"bar"}

    */

    ?>
    +
    +

    Again, unserialization yields the expected results:

    
    +<?php
      
    var_dump
    (ion\unserialize($srlzd));

    /*
      object(magic)#7 (1) {
        ["foo":"magic":private]=>
        string(3) "bar"
      }

    */

    ?>
    +
    +

    Custom serialize: +

    Customly serializable objects work like magic serializable objects, with custom names for the magic methods.

    
    +<?php
      
    class custom {
      private array 
    $data;
      function 
    init(array $data) : void {
        
    $this->data = $data;
      }
      function 
    export() : array {
        return 
    $this->data;
      }
    }

    $custom = new custom;
    $custom->init(["foo" => "bar"]);
    echo 
    $srlzd = ion\serialize($custom);

    /*
        c::custom::{data:p::custom::{foo:"bar"}}
        
    */

    ?>
    +
    +

    The above is actually the result of serializing a standard class backed PHP object, because we didn't implement any serialization primitives and did neither specify a custom method to call. So let's just do that:

    
    +<?php
      
    $srlzr 
    = new ion\Serializer\PHP(callCustomSerialize: "export");
    echo 
    $srlzd = ion\serialize($custom, $srlzr);

    /*
        C::custom::{foo:"bar"}

    */

    ?>
    +
    +

    Note how this output compares to the output of the standard magic serializable object.

    Unserialization works as used to, except sepcifying thwe custom unserialization method to call:

    
    +<?php
      
    $unsrlzr 
    = new ion\Unserializer\PHP(callCustomUnserialize: "init");
    var_dump(ion\unserialize($srlzd, $unsrlzr));

    /*
        object(custom)#10 (1) {
        ["data":"custom":private]=>
        array(1) {
          ["foo"]=>
          string(3) "bar"
        }
      }

    */

    ?>
    +
    +

    S-Expressions +

    An S-expression (or symbolic expression) is much like a list in that it’s an ordered collection of values. However, the notation aligns with Lisp syntax to connote use of application semantics like function calls or programming-language statements. As such, correct interpretation requires a higher-level context other than the raw Ion parser and data model.

    In the text format, S-expressions are bounded by parentheses. S-expressions also allow unquoted operator symbols (in addition to the unquoted identifier symbols allowed everywhere), so commas are interpreted as values rather than element separators.

    
    +null.sexp         // A null S-expression value
    ()                // An empty expression value
    (cons 1 2)        // S-expression of three values
    ([hello][there])  // S-expression containing two lists

    (a+-b)  ( 'a' '+-' 'b' )    // Equivalent; three symbols
    (a.b;)  ( 'a' '.' 'b' ';')  // Equivalent; four symbols
    +

    Although Ion S-expressions use a syntax similar to Lisp expressions, Ion does not define their interpretation or any semantics at all, beyond the pure sequence-of-values data model indicated above.


    Next up +

    +
    + + + + +
    + + + + + +
    + + diff --git a/docs/v0.1/ion/: Tutorial/:4. Symbols, Tables and Catalogs.html b/docs/v0.1/ion/: Tutorial/:4. Symbols, Tables and Catalogs.html new file mode 100644 index 0000000..2c22efd --- /dev/null +++ b/docs/v0.1/ion/: Tutorial/:4. Symbols, Tables and Catalogs.html @@ -0,0 +1,116 @@ + + + + + + ★4. Symbols, Tables and Catalogs - + mdref + + + + + + + + + + +
    + + +

    +Symbols, Tables and Catalogs

    Catalog +

    The Catalog holds a collection of ion\Symbol\Table instances queried from ion\Reader and ion\Writer instances.

    See also the ION spec's symbol guide chapter on catalog.

    
    +<?php
    $catalog 
    = new ion\Catalog;
    $symtab = ion\Symbol\PHP::asTable();
    $catalog->add($symtab);
    ?>
    +
    +
    +
    + + + + +
    + + + + + +
    + + diff --git a/docs/v0.1/ion/: Tutorial/:5. Symbols, Tables and Catalogs.html b/docs/v0.1/ion/: Tutorial/:5. Symbols, Tables and Catalogs.html new file mode 100644 index 0000000..d2c8151 --- /dev/null +++ b/docs/v0.1/ion/: Tutorial/:5. Symbols, Tables and Catalogs.html @@ -0,0 +1,137 @@ + + + + + + ★5. Symbols, Tables and Catalogs - + mdref + + + + + + + + + + +
    + + +

    +Symbols, Tables and Catalogs

    Schematic Overview +

    
    +  +---------+
      | Catalog |
      +----+----+-------------------------------+
      |    |                                    |
      |    |    +-------------+                 |
      |    +--->| SymbolTable |                 |
      |    |    +---+---------+---------------+ |
      |    |    |   |                         | |
      |    |    |   |     +-------------------+ |
      |    |    |   |     | Symbol (ID, Text) | |
      |    |    |   +---->| Symbol (ID, Text) | |
      |    |    |         | ...               | |
      |    |    +---------+-------------------+ |
      |    |                                    |
      |    |    +-------------+                 |
      |    +--->| SymbolTable |                 |
      |    |    +---+---------+---------------+ |
      |    |    |   |                         | |
      |    .    |   |     +-------------------+ |
      |    .    |   +---->| Symbol (ID, Text) | |
      |    .    |         | ...               | |
      |    .    +---------+-------------------+ |
      |    .                                    |
      +-----------------------------------------+
    +

    Catalog +

    The Catalog holds a collection of ion\Symbol\Table instances queried from ion\Reader and ion\Writer instances.

    See also the ION spec's symbol guide chapter on catalogs.

    
    +<?php
    $catalog 
    = new ion\Catalog;
    $symtab = ion\Symbol\PHP::asTable();
    $catalog->add($symtab);
    ?>
    +
    +

    Symbol Table +

    There are three types of symbol tables:

      +
    • Local
    • +
    • Shared
    • +
    • System (a special shared symbol table)
    • +

    Local symbol tables do not have names, while shared symbol tables require them; only shared symbol tables may be added to a catalog or to a writer’s list of imports.

    Local symbol tables are managed internally by Ion readers and writers. No application configuration is required to tell Ion readers or writers that local symbol tables should be used.

    Using a shared symbol table +

    Using local symbol tables requires the local symbol table (including all of its symbols) to be written at the beginning of the value stream. Consider an Ion stream that represents CSV data with many columns. Although local symbol tables will optimize writing and reading each value, including the entire symbol table itself in the value stream adds overhead that increases with the number of columns.

    If it is feasible for the writers and readers of the stream to agree on a pre-defined shared symbol table, this overhead can be reduced.

    Consider the following CSV in a file called test.csv.

    
    + id,type,state
     1,foo,false
     2,bar,true
     3,baz,true
     ...
    +

    An application that wishes to convert this data into the Ion format can generate a symbol table containing the column names. This reduces encoding size and improves read efficiency.

    Consider the following shared symbol table that declares the column names of test.csv as symbols. Note that the shared symbol table may have been generated by hand or programmatically.

    
    + $ion_shared_symbol_table::{
       name: "test.csv.columns",
       version: 1,
       symbols: ["id", "type", "state"],
     }
    +

    This shared symbol table can be stored in a file (or in a database, etc.) to be resurrected into a symbol table at runtime.

    Because the value stream written using the shared symbol table does not contain the symbol mappings, a reader of the stream needs to access the shared symbol table using a catalog.

    Consider the following complete example:

    
    +<?php

    /**
     * Representing a CSV row
     */
    class Row {
      public function 
    __construct(
        public readonly 
    int $id,
        public readonly 
    string $type,
        public readonly 
    bool $state = true
      
    ) {}
    }

    /* Fetch the shared symbol table from file, db, etc. */
    $symtab = ion\unserialize(<<<'SymbolTable'
     $ion_shared_symbol_table::{
       name: "test.csv.columns",
       version: 1,
       symbols: ["id", "type", "state"],
     }
    SymbolTable
    );

    /* Add the shared symbol table to a catalog */
    $catalog = new ion\Catalog;
    $catalog->add($symtab);

    /* Use the catalog when writing the data */
    $writer = new class(options: new ion\Writer\Options(
      
    catalog: $catalog,
      
    outputBinary: true
    )) extends ion\Writer\Buffer\Writer {
      public function 
    writeRow(Row $row) : void {
        
    $this->startContainer(ion\Type::Struct);
        
        
    $this->writeFieldname("id");
        
    $this->writeInt($row->id);
        
        
    $this->writeFieldName("type");
        
    $this->writeString($row->type);
        
        
    $this->writeFieldName("state");
        
    $this->writeBool($row->state);
        
        
    $this->finishContainer();
      }
    };

    $writer->writeRow(new Row(1, "foo", false));
    $writer->writeRow(new Row(2, "bar"));
    $writer->writeRow(new Row(3, "baz"));
    $writer->flush();

    ?>
    +
    +

    Let's inspect the binary ION stream and verify that the column names are actually replaced by SymbolIDs:

    
    +<?php
      
    foreach (str_split($writer->getBuffer(), 8) as $line) {
        
    printf("%-26s", chunk_split(bin2hex($line), 2, " "));
        foreach (
    str_split($line) as $byte) {
            echo 
    $byte >= ' ' && $byte <= '~' ? $byte : ".";
        }
        echo 
    "\n";
    }
    echo 
    "\n";

    /*
      e0 01 00 ea ee a2 81 83   ........  \ 
      de 9e 86 be 9b de 99 84   ........   |
      8e 90 74 65 73 74 2e 63   ..test.c    > here's ION symbol table metadata
      73 76 2e 63 6f 6c 75 6d   sv.colum   |
      6e 73 85 21 01 88 21 03   ns.!..!.  <
      da 8a 21 01 8b 83 66 6f   ..!...fo   |
      6f 8c 11 da 8a 21 02 8b   o....!..    > here's the actual data
      83 62 61 72 8c 11 da 8a   .bar....   |
      21 03 8b 83 62 61 7a 8c   !...baz.  /
      11                        .
    */

    ?>
    +
    +

    When unserializing without knowing the used symbols, our column name will actually be just symbol IDs $<SID>:

    
    +<?php

    var_dump
    (ion\unserialize($writer->getBuffer(), [
      
    "multiSequence" => true,
    ]));

    /*
    array(3) {
      [0]=>
      array(3) {
        ["$10"]=>
        int(1)
        ["$11"]=>
        string(3) "foo"
        ["$12"]=>
        bool(false)
      }
      [1]=>
      array(3) {
        ["$10"]=>
        int(2)
        ["$11"]=>
        string(3) "bar"
        ["$12"]=>
        bool(true)
      }
      [2]=>
      array(3) {
        ["$10"]=>
        int(3)
        ["$11"]=>
        string(3) "baz"
        ["$12"]=>
        bool(true)
      }
    }
    */

    ?>
    +
    +

    When unserializing with known symbols, the symbol IDs will be resolved when using the catatalog with the appropriate symbol tables:

    
    +<?php
      
    var_dump
    (ion\unserialize($writer->getBuffer(), [
      
    "multiSequence" => true,
      
    "readerOptions" => [
        
    "catalog" => $catalog
      
    ]
    ]));

    /*
      array(3) {
        [0]=>
        array(3) {
          ["id"]=>
          int(1)
          ["type"]=>
          string(3) "foo"
          ["state"]=>
          bool(false)
        }
        [1]=>
        array(3) {
          ["id"]=>
          int(2)
          ["type"]=>
          string(3) "bar"
          ["state"]=>
          bool(true)
        }
        [2]=>
        array(3) {
          ["id"]=>
          int(3)
          ["type"]=>
          string(3) "baz"
          ["state"]=>
          bool(true)
        }
      }
    */

    ?>
    +
    +
    +
    + + + + +
    + + + + + +
    + + diff --git a/docs/v0.1/ion/: Tutorial/Untitled.html b/docs/v0.1/ion/: Tutorial/Untitled.html new file mode 100644 index 0000000..b1ec579 --- /dev/null +++ b/docs/v0.1/ion/: Tutorial/Untitled.html @@ -0,0 +1,111 @@ + + + + + + Untitled - + mdref + + + + + + + + + + +
    + + + +
    + + + + +
    + + + + + +
    + + diff --git a/docs/v0.1/ion/Catalog.html b/docs/v0.1/ion/Catalog.html index 2769b30..5f274e9 100644 --- a/docs/v0.1/ion/Catalog.html +++ b/docs/v0.1/ion/Catalog.html @@ -74,6 +74,8 @@
  • ★ Contributing
  • ★ Security
  • + +
  • ★ Tutorial
  • Decimal
  • diff --git a/docs/v0.1/ion/Decimal.html b/docs/v0.1/ion/Decimal.html index 29fcf13..e3ac535 100644 --- a/docs/v0.1/ion/Decimal.html +++ b/docs/v0.1/ion/Decimal.html @@ -99,6 +99,8 @@
  • ★ Security
  • +
  • ★ Tutorial
  • +
  • Catalog
  • Exception
  • diff --git a/docs/v0.1/ion/Exception.html b/docs/v0.1/ion/Exception.html index 22a3981..14c6938 100644 --- a/docs/v0.1/ion/Exception.html +++ b/docs/v0.1/ion/Exception.html @@ -46,6 +46,8 @@
  • ★ Security
  • +
  • ★ Tutorial
  • +
  • Catalog
  • Decimal
  • diff --git a/docs/v0.1/ion/LOB.html b/docs/v0.1/ion/LOB.html index bcdb530..593ca05 100644 --- a/docs/v0.1/ion/LOB.html +++ b/docs/v0.1/ion/LOB.html @@ -55,6 +55,8 @@
  • ★ Security
  • +
  • ★ Tutorial
  • +
  • Catalog
  • Decimal
  • diff --git a/docs/v0.1/ion/Reader.html b/docs/v0.1/ion/Reader.html index b821573..592047d 100644 --- a/docs/v0.1/ion/Reader.html +++ b/docs/v0.1/ion/Reader.html @@ -224,6 +224,8 @@
  • ★ Security
  • +
  • ★ Tutorial
  • +
  • Catalog
  • Decimal
  • diff --git a/docs/v0.1/ion/Serializer.html b/docs/v0.1/ion/Serializer.html index 4e69a3c..f73d5d8 100644 --- a/docs/v0.1/ion/Serializer.html +++ b/docs/v0.1/ion/Serializer.html @@ -60,6 +60,8 @@
  • ★ Security
  • +
  • ★ Tutorial
  • +
  • Catalog
  • Decimal
  • diff --git a/docs/v0.1/ion/Serializer/PHP.html b/docs/v0.1/ion/Serializer/PHP.html index 199daea..811de60 100644 --- a/docs/v0.1/ion/Serializer/PHP.html +++ b/docs/v0.1/ion/Serializer/PHP.html @@ -73,7 +73,7 @@

    None.

    Properties:

    diff --git a/docs/v0.1/ion/Serializer/PHP/__construct.html b/docs/v0.1/ion/Serializer/PHP/__construct.html index 37126a6..666e2a1 100644 --- a/docs/v0.1/ion/Serializer/PHP/__construct.html +++ b/docs/v0.1/ion/Serializer/PHP/__construct.html @@ -67,9 +67,9 @@

    -void ion\Serializer\PHP::__construct([?ion\Writer\Options $writerOptions = NULL, [bool $multiSequence = false, [bool $callMagicSerialize = true, [?string $callCustomSerialize = NULL]]]])

    Create a new PHP ION serializer.

    Params: +void ion\Serializer\PHP::__construct([ion\Writer\Options|array|null $writerOptions = NULL, [bool $multiSequence = false, [bool $callMagicSerialize = true, [?string $callCustomSerialize = NULL]]]])

    Create a new PHP ION serializer.

    Params:

    Namespaces, Interfaces and Classes: diff --git a/docs/v0.1/ion/Timestamp/__construct.html b/docs/v0.1/ion/Timestamp/__construct.html index 13f6c66..6e49cba 100644 --- a/docs/v0.1/ion/Timestamp/__construct.html +++ b/docs/v0.1/ion/Timestamp/__construct.html @@ -61,7 +61,7 @@

    -void ion\Timestamp::__construct(ion\Timestamp\Precision|int $precision, [ion\Timestamp\Format|string|null $format = NULL, [?string $datetime = NULL, [?DateTimeZone $timezone = NULL]]])

    Create a new ION timestamp.

    Params: +void ion\Timestamp::__construct(ion\Timestamp\Precision|int $precision, [ion\Timestamp\Format|string|null $format = NULL, [?string $datetime = NULL, [DateTimeZone|string|null $timezone = NULL]]])

    Create a new ION timestamp.

    Params:

    diff --git a/docs/v0.1/ion/Type.html b/docs/v0.1/ion/Type.html index b4e6496..f98f2e2 100644 --- a/docs/v0.1/ion/Type.html +++ b/docs/v0.1/ion/Type.html @@ -46,6 +46,8 @@
  • ★ Security
  • +
  • ★ Tutorial
  • +
  • Catalog
  • Decimal
  • @@ -82,7 +84,7 @@
  • ion\Decimal
  • ion\Timestamp
  • ion\Symbol
  • -
  • ion\Lob
  • +
  • ion\Lob
  • Constants:

    • diff --git a/docs/v0.1/ion/Unserializer.html b/docs/v0.1/ion/Unserializer.html index ce2ff73..96819a6 100644 --- a/docs/v0.1/ion/Unserializer.html +++ b/docs/v0.1/ion/Unserializer.html @@ -60,6 +60,8 @@
    • ★ Security
    • +
    • ★ Tutorial
    • +
    • Catalog
    • Decimal
    • diff --git a/docs/v0.1/ion/Unserializer/PHP.html b/docs/v0.1/ion/Unserializer/PHP.html index ca717f8..79651ea 100644 --- a/docs/v0.1/ion/Unserializer/PHP.html +++ b/docs/v0.1/ion/Unserializer/PHP.html @@ -73,7 +73,7 @@

      None.

      Properties:

      diff --git a/docs/v0.1/ion/Unserializer/PHP/__construct.html b/docs/v0.1/ion/Unserializer/PHP/__construct.html index 62bf8a8..11eda85 100644 --- a/docs/v0.1/ion/Unserializer/PHP/__construct.html +++ b/docs/v0.1/ion/Unserializer/PHP/__construct.html @@ -67,9 +67,9 @@

    -void ion\Unserializer\PHP::__construct([?ion\Reader\Options $readerOptions = NULL, [bool $multiSequence = false, [bool $callMagicUnserialize = true, [?string $callCustomUnserialize = NULL]]]])

    Create a new ION PHP unserializer.

    Params: +void ion\Unserializer\PHP::__construct([ion\Reader\Options|array|null $readerOptions = NULL, [bool $multiSequence = false, [bool $callMagicUnserialize = true, [?string $callCustomUnserialize = NULL]]]])

    Create a new ION PHP unserializer.

    Params:

      -
    • Optional ?ion\Reader\Options $readerOptions = NULL
      +
    • Optional ion\Reader\Options|array|null $readerOptions = NULL
      Reader options.
    • Optional bool $multiSequence = false
      Whether to continue reading multiple ION sequences after the first one.
    • diff --git a/docs/v0.1/ion/Writer.html b/docs/v0.1/ion/Writer.html index 590c6dd..28d049a 100644 --- a/docs/v0.1/ion/Writer.html +++ b/docs/v0.1/ion/Writer.html @@ -189,6 +189,8 @@
    • ★ Security
    • +
    • ★ Tutorial
    • +
    • Catalog
    • Decimal
    • diff --git a/docs/v0.1/ion/serialize.html b/docs/v0.1/ion/serialize.html index 73c5e46..4a5ca4e 100644 --- a/docs/v0.1/ion/serialize.html +++ b/docs/v0.1/ion/serialize.html @@ -46,6 +46,8 @@
    • ★ Security
    • +
    • ★ Tutorial
    • +
    • Catalog
    • Decimal
    • @@ -77,7 +79,7 @@

    -string ion\serialize(mixed $data, [?ion\Serializer $serializer = NULL])

    Serialize a PHP value as ION data.

    Serializes supported PHP values with the optionally provided \ion\Serializer: