# ---
-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
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 $^ $@
-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
.PHONY: clean
clean:
-rm -rf latest src vendor composer* .composer
-
-
--- /dev/null
+# 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
+```
--- /dev/null
+# 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 <path/to/pecl.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 <path/to/pecl.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
--- /dev/null
+# 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
+<?=
+ion\serialize([
+ "key" => "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
+<?=
+json_encode([
+ "key" => "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
+<?=
+var_representation(
+ ion\unserialize('{key:"value",more:{data:123}}')
+);
+?>
+```
+
+##### 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
+<?=
+var_representation(
+ ion\unserialize('{"key":"value","more":{"data":123}}')
+);
+?>
+```
+
+##### Output:
+
+```php
+[
+ 'key' => 'value',
+ 'more' => [
+ 'data' => 123,
+ ],
+]
+```
+
+### Multiple documents
+
+Ion supports multiple sequences of documents within a single stream; consider the following:
+
+```php
+<?=
+var_representation(
+ ion\unserialize('
+ {"key":"value","more":{"data":123}}
+ {"key":"value","more":{"data":456}}
+ ', new ion\Unserializer\PHP(multiSequence: true)
+ )
+);
+?>
+```
+
+#### 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
+<?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
+<?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
+
+* [Standard Datatypes](ion/:%20Tutorial/:3.%20Standard%20Datatypes)
--- /dev/null
+# 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
+<?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
+<?php
+
+$writer->writeBool(true);
+$writer->writeBool(false);
+$writer->flush();
+
+/*
+ true
+ false
+*/
+
+?>
+```
+
+## Integers
+
+The int type comprises signed integers of arbitrary size.
+
+```php
+<?php
+
+$writer->writeInt(123);
+$writer->writeInt("12345678901234567890");
+$writer->flush();
+
+/*
+ 123
+ 12345678901234567890
+*/
+
+?>
+```
+
+In ION-Text, underscores are allowed to separate digits:
+
+```php
+<?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
+<?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
+<?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
+<?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](https://amzn.github.io/ion-docs/docs/spec.html#escapess)). The binary format always uses UTF-8 encoding.
+
+```php
+<?=
+
+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
+<?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.
+
+```php
+<?=
+
+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.
+
+```php
+<?=
+
+ion\serialize([
+ "outlaw",
+ "key" => "value",
+ "obj" => (object)["key" => "value"]
+]);
+
+/*
+ {'0':"outlaw",key:"value",obj:o::{key:"value"}}
+*/
+
+?>
+```
+
+```php
+<?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
+
+* [Special Datatypes](ion/:%20Tutorial/:4.%20Special%20Datatypes)
--- /dev/null
+# 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
+<?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](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
+<?=
+new ion\Timestamp(
+ precision: ion\Timestamp\Precision::FracTZ,
+)
+
+ // 2022-02-25T16:11:54.118+00:00
+
+?>
+```
+
+```php
+<?=
+new ion\Timestamp(
+ precision: ion\Timestamp\Precision::Day
+)
+
+ // 2022-02-25T
+
+?>
+```
+
+```php
+<?=
+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](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
+<?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
+<?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
+<?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
+<?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
+<?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
+<?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
+<?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](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
--- /dev/null
+# 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
+<?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
+<?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
+<?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
+<?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
+<?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)
+ }
+ }
+*/
+
+?>
+```
+
<a href="ion.stub.php">ion.stub.php</a><br>
<small>
Last modified:
- 2022-01-28 09:29:47 UTC </small>
+ 2022-03-03 08:45:59 UTC </small>
</li>
</ul>
</div>
</li>
+ <li>
+ ↳ <a href="./ion/: Tutorial">★ Tutorial</a>
+
+ </li>
+
<li>
↳ <a href="./ion/Catalog">Catalog</a>
<a href="ion.stub.php">ion.stub.php</a><br>
<small>
Last modified:
- 2022-01-28 09:29:47 UTC </small>
+ 2022-03-03 08:45:59 UTC </small>
</li>
</ul>
</div><h2 id="Functions:">Functions:<a class="permalink" href="ion#Functions:">#</a>
</h3>
<p>Serialize a PHP value as ION data.</p>
- <p><code><a href="https://php.net/manual/en/language.types.string">string</a></code> <a href="ion/serialize">ion\serialize</a>(<code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.mixed">mixed</a></code> <span class="var">$data</span>, [?<a href="ion/Serializer">ion\Serializer</a> <span class="var">$serializer</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>])</p>
+ <p><code><a href="https://php.net/manual/en/language.types.string">string</a></code> <a href="ion/serialize">ion\serialize</a>(<code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.mixed">mixed</a></code> <span class="var">$data</span>, [<a href="ion/Serializer">ion\Serializer</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$serializer</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>])</p>
</li>
<li>
</h3>
<p>Unserialize ION data (stream) as PHP value(s).</p>
- <p><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.mixed">mixed</a></code> <a href="ion/unserialize">ion\unserialize</a>(<code><a href="https://php.net/manual/en/language.types.string">string</a></code>|<code><a href="https://php.net/manual/en/language.types.resource">resource</a></code> <span class="var">$data</span>, [?<a href="ion/Unserializer">ion\Unserializer</a> <span class="var">$unserializer</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>])</p>
+ <p><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.mixed">mixed</a></code> <a href="ion/unserialize">ion\unserialize</a>(<code><a href="https://php.net/manual/en/language.types.string">string</a></code>|<code><a href="https://php.net/manual/en/language.types.resource">resource</a></code> <span class="var">$data</span>, [<a href="ion/Unserializer">ion\Unserializer</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$unserializer</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>])</p>
</li>
</ul><h2 id="Namespaces.Interfaces.and.Classes:">Namespaces, Interfaces and Classes:<a class="permalink" href="ion#Namespaces.Interfaces.and.Classes:">#</a>
* * 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).
* @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.
* @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 {}
/**
* 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.
*/
/**
* 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.
*/
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
<li>↲ <a href="./ion/: Contributing">★ Contributing</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
--- /dev/null
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ ★ Tutorial -
+ mdref
+ </title>
+ <meta property="og:title" content="ion/: Tutorial">
+ <meta name="viewport" content="width=1200, initial-scale=0.5">
+ <base href="/ext-ion/v0.1/">
+ <meta http-equiv="Content-Location" content="/ext-ion/v0.1/ion/: Tutorial">
+ <link rel="stylesheet" href="index.css">
+
+ <link rel="shortcut icon" href="/ext-ion/v0.1/favicon.ico">
+ </head>
+ <body>
+ <div class="page">
+
+<div class="sidebar">
+
+ <div class="edit">
+ <a href="https://github.com/awesomized/ext-ion/edit/master/ion.stub.php">Edit</a>
+ </div>
+
+
+ <ul>
+ <li>↰ <a href="./">Home</a>
+
+ <ul>
+ <li>
+
+ ↑ <a href="./ion">
+ ion
+ </a>
+ <ul>
+ <li>
+
+ ↻ <strong><a href="./ion/: Tutorial">★ Tutorial</a></strong>
+
+
+ <ul>
+
+ <li>
+ ↳ <a href="./ion/: Tutorial/:1. Getting started">★1. Getting started</a>
+
+ </li>
+
+ <li>
+ ↳ <a href="./ion/: Tutorial/:2. What is ion">★2. What is ion</a>
+
+ </li>
+
+ <li>
+ ↳ <a href="./ion/: Tutorial/:3. Standard Datatypes">★3. Standard Datatypes</a>
+
+ </li>
+
+ <li>
+ ↳ <a href="./ion/: Tutorial/:4. Special Datatypes">★4. Special Datatypes</a>
+
+ </li>
+
+ <li>
+ ↳ <a href="./ion/: Tutorial/:5. Symbols, Tables and Catalogs">★5. Symbols, Tables and Catalogs</a>
+
+ </li>
+
+ </ul>
+
+
+ </ul>
+
+ <li>↲ <a href="./ion/: Contributing">★ Contributing</a></li>
+
+ <li>↲ <a href="./ion/: Security">★ Security</a></li>
+
+ <li>↲ <a href="./ion/Catalog">Catalog</a></li>
+
+ <li>↲ <a href="./ion/Decimal">Decimal</a></li>
+
+ <li>↲ <a href="./ion/Exception">Exception</a></li>
+
+ <li>↲ <a href="./ion/LOB">LOB</a></li>
+
+ <li>↲ <a href="./ion/Reader">Reader</a></li>
+
+ <li>↲ <a href="./ion/Serializer">Serializer</a></li>
+
+ <li>↲ <a href="./ion/Symbol">Symbol</a></li>
+
+ <li>↲ <a href="./ion/Timestamp">Timestamp</a></li>
+
+ <li>↲ <a href="./ion/Type">Type</a></li>
+
+ <li>↲ <a href="./ion/Unserializer">Unserializer</a></li>
+
+ <li>↲ <a href="./ion/Writer">Writer</a></li>
+
+ <li>↲ <a href="./ion/serialize">serialize</a></li>
+
+ <li>↲ <a href="./ion/unserialize">unserialize</a></li>
+
+ </li>
+ </ul>
+
+ </li>
+ </ul>
+</div>
+ <meta charset="utf-8"><h1>
+<a class="permalink" href="ion/:%20Tutorial#">#</a>Tutorial</h1><p>Welcome to the ext-ion tutorial. We'll look into what Amazon's ION format is and how to use it from within PHP.</p><ol>
+<li>★1. <a href="ion/:%20Tutorial/:1.%20Getting%20started">Getting started</a>
+</li>
+<li>★2. <a href="ion/:%20Tutorial/:2.%20What%20is%20ion">What is ion?</a>
+</li>
+<li>★3. <a href="ion/:%20Tutorial/:3.%20Standard%20Datatypes">Standard Datatypes</a>
+</li>
+<li>★4. <a href="ion/:%20Tutorial/:4.%20Special%20Datatypes">Special Datatypes</a>
+</li>
+<li>★5. <a href="ion/:%20Tutorial/:4.%20Symbols,%20Tables%20and%20Catalogs">Symbols, Tables and Catalogs</a>
+</li>
+</ol><blockquote>
+<p>Parts of this documentation are replicated verbatim of the official <a href="https://amzn.github.io/ion-docs/">Amazon ION documentation</a> licensed under the Apache 2.0 License.</p>
+</blockquote><pre><code><span style="color: inherit" class="html">
+ Apache License<br> Version 2.0, January 2004<br> http://www.apache.org/licenses/<br><br> TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION<br><br> 1. Definitions.<br><br> "License" shall mean the terms and conditions for use, reproduction,<br> and distribution as defined by Sections 1 through 9 of this document.<br><br> "Licensor" shall mean the copyright owner or entity authorized by<br> the copyright owner that is granting the License.<br><br> "Legal Entity" shall mean the union of the acting entity and all<br> other entities that control, are controlled by, or are under common<br> control with that entity. For the purposes of this definition,<br> "control" means (i) the power, direct or indirect, to cause the<br> direction or management of such entity, whether by contract or<br> otherwise, or (ii) ownership of fifty percent (50%) or more of the<br> outstanding shares, or (iii) beneficial ownership of such entity.<br><br> "You" (or "Your") shall mean an individual or Legal Entity<br> exercising permissions granted by this License.<br><br> "Source" form shall mean the preferred form for making modifications,<br> including but not limited to software source code, documentation<br> source, and configuration files.<br><br> "Object" form shall mean any form resulting from mechanical<br> transformation or translation of a Source form, including but<br> not limited to compiled object code, generated documentation,<br> and conversions to other media types.<br><br> "Work" shall mean the work of authorship, whether in Source or<br> Object form, made available under the License, as indicated by a<br> copyright notice that is included in or attached to the work<br> (an example is provided in the Appendix below).<br><br> "Derivative Works" shall mean any work, whether in Source or Object<br> form, that is based on (or derived from) the Work and for which the<br> editorial revisions, annotations, elaborations, or other modifications<br> represent, as a whole, an original work of authorship. For the purposes<br> of this License, Derivative Works shall not include works that remain<br> separable from, or merely link (or bind by name) to the interfaces of,<br> the Work and Derivative Works thereof.<br><br> "Contribution" shall mean any work of authorship, including<br> the original version of the Work and any modifications or additions<br> to that Work or Derivative Works thereof, that is intentionally<br> submitted to Licensor for inclusion in the Work by the copyright owner<br> or by an individual or Legal Entity authorized to submit on behalf of<br> the copyright owner. For the purposes of this definition, "submitted"<br> means any form of electronic, verbal, or written communication sent<br> to the Licensor or its representatives, including but not limited to<br> communication on electronic mailing lists, source code control systems,<br> and issue tracking systems that are managed by, or on behalf of, the<br> Licensor for the purpose of discussing and improving the Work, but<br> excluding communication that is conspicuously marked or otherwise<br> designated in writing by the copyright owner as "Not a Contribution."<br><br> "Contributor" shall mean Licensor and any individual or Legal Entity<br> on behalf of whom a Contribution has been received by Licensor and<br> subsequently incorporated within the Work.<br><br> 2. Grant of Copyright License. Subject to the terms and conditions of<br> this License, each Contributor hereby grants to You a perpetual,<br> worldwide, non-exclusive, no-charge, royalty-free, irrevocable<br> copyright license to reproduce, prepare Derivative Works of,<br> publicly display, publicly perform, sublicense, and distribute the<br> Work and such Derivative Works in Source or Object form.<br><br> 3. Grant of Patent License. Subject to the terms and conditions of<br> this License, each Contributor hereby grants to You a perpetual,<br> worldwide, non-exclusive, no-charge, royalty-free, irrevocable<br> (except as stated in this section) patent license to make, have made,<br> use, offer to sell, sell, import, and otherwise transfer the Work,<br> where such license applies only to those patent claims licensable<br> by such Contributor that are necessarily infringed by their<br> Contribution(s) alone or by combination of their Contribution(s)<br> with the Work to which such Contribution(s) was submitted. If You<br> institute patent litigation against any entity (including a<br> cross-claim or counterclaim in a lawsuit) alleging that the Work<br> or a Contribution incorporated within the Work constitutes direct<br> or contributory patent infringement, then any patent licenses<br> granted to You under this License for that Work shall terminate<br> as of the date such litigation is filed.<br><br> 4. Redistribution. You may reproduce and distribute copies of the<br> Work or Derivative Works thereof in any medium, with or without<br> modifications, and in Source or Object form, provided that You<br> meet the following conditions:<br><br> (a) You must give any other recipients of the Work or<br> Derivative Works a copy of this License; and<br><br> (b) You must cause any modified files to carry prominent notices<br> stating that You changed the files; and<br><br> (c) You must retain, in the Source form of any Derivative Works<br> that You distribute, all copyright, patent, trademark, and<br> attribution notices from the Source form of the Work,<br> excluding those notices that do not pertain to any part of<br> the Derivative Works; and<br><br> (d) If the Work includes a "NOTICE" text file as part of its<br> distribution, then any Derivative Works that You distribute must<br> include a readable copy of the attribution notices contained<br> within such NOTICE file, excluding those notices that do not<br> pertain to any part of the Derivative Works, in at least one<br> of the following places: within a NOTICE text file distributed<br> as part of the Derivative Works; within the Source form or<br> documentation, if provided along with the Derivative Works; or,<br> within a display generated by the Derivative Works, if and<br> wherever such third-party notices normally appear. The contents<br> of the NOTICE file are for informational purposes only and<br> do not modify the License. You may add Your own attribution<br> notices within Derivative Works that You distribute, alongside<br> or as an addendum to the NOTICE text from the Work, provided<br> that such additional attribution notices cannot be construed<br> as modifying the License.<br><br> You may add Your own copyright statement to Your modifications and<br> may provide additional or different license terms and conditions<br> for use, reproduction, or distribution of Your modifications, or<br> for any such Derivative Works as a whole, provided Your use,<br> reproduction, and distribution of the Work otherwise complies with<br> the conditions stated in this License.<br><br> 5. Submission of Contributions. Unless You explicitly state otherwise,<br> any Contribution intentionally submitted for inclusion in the Work<br> by You to the Licensor shall be under the terms and conditions of<br> this License, without any additional terms or conditions.<br> Notwithstanding the above, nothing herein shall supersede or modify<br> the terms of any separate license agreement you may have executed<br> with Licensor regarding such Contributions.<br><br> 6. Trademarks. This License does not grant permission to use the trade<br> names, trademarks, service marks, or product names of the Licensor,<br> except as required for reasonable and customary use in describing the<br> origin of the Work and reproducing the content of the NOTICE file.<br><br> 7. Disclaimer of Warranty. Unless required by applicable law or<br> agreed to in writing, Licensor provides the Work (and each<br> Contributor provides its Contributions) on an "AS IS" BASIS,<br> WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or<br> implied, including, without limitation, any warranties or conditions<br> of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A<br> PARTICULAR PURPOSE. You are solely responsible for determining the<br> appropriateness of using or redistributing the Work and assume any<br> risks associated with Your exercise of permissions under this License.<br><br> 8. Limitation of Liability. In no event and under no legal theory,<br> whether in tort (including negligence), contract, or otherwise,<br> unless required by applicable law (such as deliberate and grossly<br> negligent acts) or agreed to in writing, shall any Contributor be<br> liable to You for damages, including any direct, indirect, special,<br> incidental, or consequential damages of any character arising as a<br> result of this License or out of the use or inability to use the<br> Work (including but not limited to damages for loss of goodwill,<br> work stoppage, computer failure or malfunction, or any and all<br> other commercial damages or losses), even if such Contributor<br> has been advised of the possibility of such damages.<br><br> 9. Accepting Warranty or Additional Liability. While redistributing<br> the Work or Derivative Works thereof, You may choose to offer,<br> and charge a fee for, acceptance of support, warranty, indemnity,<br> or other liability obligations and/or rights consistent with this<br> License. However, in accepting such obligations, You may act only<br> on Your own behalf and on Your sole responsibility, not on behalf<br> of any other Contributor, and only if You agree to indemnify,<br> defend, and hold each Contributor harmless for any liability<br> incurred by, or claims asserted against, such Contributor by reason<br> of your accepting any such warranty or additional liability.<br><br> END OF TERMS AND CONDITIONS<br></span>
+</code></pre>
+ <div class="comments">
+ <style>.giscus-frame {min-height: 16em;}</style>
+ <script>
+ function giscus_load(button) {
+ let script = document.createElement("script");
+ script.setAttribute("data-repo", 'awesomized/ext-ion');
+ script.setAttribute("data-category", 'Comments on Docs');
+ script.setAttribute("data-repo-id", 'R_kgDOGfXEXw');
+ script.setAttribute("data-category-id", 'DIC_kwDOGfXEX84CBHuf');
+ script.setAttribute("data-mapping", 'og:title');
+ script.setAttribute("data-input-position", 'bottom');
+ script.setAttribute("data-reactions-enabled", false);
+ script.setAttribute("data-theme", 'light');
+ script.setAttribute("data-lang", 'en');
+
+ script.src = "//giscus.app/client.js";
+ button.parentNode.replaceChild(script, button);
+ }
+ </script>
+ <button class="activator" onclick="giscus_load(this)">Show Comments from Github Discussions</button>
+
+ </div>
+
+ <footer>
+
+<ul>
+ <li><a href="https://github.com/m6w6/mdref">mdref-v3.0
+</a></li>
+ <li><a href="LICENSE">© 2013-2022 All rights reserved.</a></li>
+ <li>
+</li>
+</ul>
+
+ </footer>
+
+ <script src="index.js" defer></script>
+
+ </div>
+ </body>
+</html>
--- /dev/null
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ ★1. Getting started -
+ mdref
+ </title>
+ <meta property="og:title" content="ion/: Tutorial/:1. Getting started">
+ <meta name="viewport" content="width=1200, initial-scale=0.5">
+ <base href="/ext-ion/v0.1/">
+ <meta http-equiv="Content-Location" content="/ext-ion/v0.1/ion/: Tutorial/:1. Getting started">
+ <link rel="stylesheet" href="index.css">
+
+ <link rel="shortcut icon" href="/ext-ion/v0.1/favicon.ico">
+ </head>
+ <body>
+ <div class="page">
+
+<div class="sidebar">
+
+ <div class="edit">
+ <a href="https://github.com/awesomized/ext-ion/edit/master/ion.stub.php">Edit</a>
+ </div>
+
+
+ <ul>
+ <li>↰ <a href="./">Home</a>
+
+ <ul>
+ <li>
+
+ ↑ <a href="./ion">
+ ion
+ </a>
+ <ul>
+ <li>
+
+ ↑ <a href="./ion/: Tutorial">
+ ★ Tutorial
+ </a>
+ <ul>
+ <li>
+
+ ↻ <strong><a href="./ion/: Tutorial/:1. Getting started">★1. Getting started</a></strong>
+
+
+
+ </ul>
+
+ <li>↲ <a href="./ion/: Tutorial/:2. What is ion">★2. What is ion</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:3. Standard Datatypes">★3. Standard Datatypes</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:4. Special Datatypes">★4. Special Datatypes</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:5. Symbols, Tables and Catalogs">★5. Symbols, Tables and Catalogs</a></li>
+
+ </ul>
+
+ </li>
+ </ul>
+
+ </li>
+ </ul>
+</div>
+ <meta charset="utf-8"><h1>
+<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#">#</a>Getting started</h1><p>The PHP extension for Ion requires <strong>PHP version 8.1</strong> or greater, see the <a href="ion/:%20Tutorial/:1.%20Getting%20started#Install">Install</a> section.</p><h2 id="Why.Ion.">Why Ion?<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Why.Ion.">#</a>
+</h2><ul>
+<li>Ion provides <strong><a href="ion/:%20Tutorial/:1.%20Getting%20started#Dual-format.interoperability">dual-format interoperability</a></strong>, 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.</li>
+<li>Ion’s <strong><a href="ion/:%20Tutorial/:1.%20Getting%20started#Rich.type.system">rich type system</a></strong> <em>extends</em> 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.</li>
+<li>Ion is a <strong><a href="ion/:%20Tutorial/:1.%20Getting%20started#Self-describing">self-describing</a></strong> 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.</li>
+<li>Because most data is read more often than it is written, Ion defines a <strong><a href="ion/:%20Tutorial/:1.%20Getting%20started#Read-optimized.binary.format">read-optimized binary format</a></strong>.</li>
+</ul><h3 id="Dual-format.interoperability">Dual-format interoperability<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Dual-format.interoperability">#</a>
+</h3><p>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.</p><p>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.</p><h4 id="Ease.of.use">Ease of use<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Ease.of.use">#</a>
+</h4><p>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.</p><p>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.</p><h4 id="Seamless.transcoding">Seamless transcoding<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Seamless.transcoding">#</a>
+</h4><p>Ion’s interoperable formats avoid the kinds of semantic mismatches encountered when attempting to mix and match separate text and binary formats.</p><p>Standalone binary formats such as <a href="http://cbor.io/">CBOR</a> 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 <code>bignum</code> must be base-64 encoded and represented as a JSON <code>string</code> in order to avoid numeric overflow when read by a JSON parser, while a CBOR <code>map</code> may be directly converted to a JSON <code>object</code> only if all its keys are UTF-8 strings.</p><h3 id="Rich.type.system">Rich type system<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Rich.type.system">#</a>
+</h3><p>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 <code>number</code> 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 <code>number</code> 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.</p><h4 id="Timestamps">Timestamps<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Timestamps">#</a>
+</h4><p>Ion <a href="ion/:%20Tutorial/:4.%20Special%20Datatypes#Timestamps">timestamps</a> 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.</p><p>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.</p><h4 id="Blobs.and.Clobs">Blobs and Clobs<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Blobs.and.Clobs">#</a>
+</h4><p>Ion’s <a href="ion/:%20Tutorial/:4.%20Special%20Datatypes#BLob"><code>blob</code></a> and <a href="ion/:%20Tutorial/:4.%20Special%20Datatypes#CLob"><code>clob</code></a> 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.</p><p>For example, a <code>blob</code> could be used to transmit a bitmap image, while a <code>clob</code> could be used to transmit Shift JIS text or an XML payload.</p><h4 id="Symbolic.expressions">Symbolic expressions<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Symbolic.expressions">#</a>
+</h4><p>The Ion specification defines a distinct syntax for <a href="ion/:%20Tutorial/:4.%20Special%20Datatypes#S-Expressions">symbolic expression</a>s (<em>S-expressions</em>), but does not define how they should be processed. This allows applications to use S-expressions to convey domain-specific semantics in a first-<em>class</em> Ion type.</p><p>Formats that lack S-expressions as a first-<em>class</em> type are often left to choose between two imperfect options: adding a pre-processor (e.g. <a href="http://jsonnet.org/">Jsonnet</a> 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.</p><h4 id="Annotations">Annotations<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Annotations">#</a>
+</h4><p>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 <em>annotations</em> are not interpreted by Ion readers and may be used, for example, to add type information to a <code>struct</code>, time units to an <code><a href="https://php.net/manual/en/language.types.integer">integer</a></code> or decimal value, or a description of the contents of a blob value.</p><h3 id="Self-describing">Self-describing<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Self-describing">#</a>
+</h3><p>Like JSON and CBOR, Ion is a <em>self</em>-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 <a href="https://developers.google.com/protocol-buffers/">protocol buffers</a>, <a href="http://thrift.apache.org/">Thrift</a>, and <a href="https://avro.apache.org/">Avro</a>, 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.</p><h3 id="Read-optimized.binary.format">Read-optimized binary format<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Read-optimized.binary.format">#</a>
+</h3><p>Ion’s binary format is optimized according to the following principles:</p><ul>
+<li>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.</li>
+<li>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.</li>
+</ul><p>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.</p><h4 id="Length-prefixing">Length-prefixing<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Length-prefixing">#</a>
+</h4><p>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.</p><h4 id="Symbol.tables">Symbol tables<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Symbol.tables">#</a>
+</h4><p>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.</p><h2 id="Install">Install<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Install">#</a>
+</h2><p>You can get started installing ext-ion the usual ways:</p><h3 id="PECL">PECL<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#PECL">#</a>
+</h3><p><code>pecl install ion</code></p><h3 id="Trinity">Trinity<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Trinity">#</a>
+</h3><pre><code><span style="color: inherit" class="html">
+./configure<br>make #-j$(nproc)<br>sudo make install #INSTALL=install<br></span>
+</code></pre><h3 id="PHARext">PHARext<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#PHARext">#</a>
+</h3><p>See <a href="https://pharext.org">https://pharext.org</a> and <a href="https://replicator.pharext.org/?ion">https://replicator.pharext.org/?ion</a></p><h4 id="Quick:">Quick:<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Quick:">#</a>
+</h4><pre><code><span style="color: inherit" class="html">
+curl -sSO https://replicator.pharext.org/phars/ion/ion-0.1.0.ext.phar<br>php ./ion-0.1.0.ext.phar --sudo --ini <path/to/pecl.ini><br></span>
+</code></pre><h4 id="Verified:">Verified:<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Verified:">#</a>
+</h4><pre><code><span style="color: inherit" class="html">
+# download phar, signature and public key<br>curl -sSO https://replicator.pharext.org/replicator.pub<br>curl -sSO https://replicator.pharext.org/phars/ion/ion-0.1.0.ext.phar<br>curl -sSO https://replicator.pharext.org/sigs/ion/ion-0.1.0.ext.phar.sig<br><br># verify signature against public key<br>openssl dgst \<br> -verify replicator.pub \<br> -signature ion-0.1.0.ext.phar.sig \<br> ion-0.1.0.ext.phar<br><br># install verified extension<br>php ./ion-0.1.0.ext.phar --sudo --ini <path/to/pecl.ini><br><br></span>
+</code></pre><h2 id="Check">Check<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Check">#</a>
+</h2><p><code>php -m | grep ^ion</code> should show: <code>ion</code>.</p><hr><h2 id="Next.up">Next up<a class="permalink" href="ion/:%20Tutorial/:1.%20Getting%20started#Next.up">#</a>
+</h2><ul>
+<li>
+<a href="ion/:%20Tutorial/:2.%20What%20is%20ion">What is ion?</a>
+</li>
+</ul>
+ <div class="comments">
+ <style>.giscus-frame {min-height: 16em;}</style>
+ <script>
+ function giscus_load(button) {
+ let script = document.createElement("script");
+ script.setAttribute("data-repo", 'awesomized/ext-ion');
+ script.setAttribute("data-category", 'Comments on Docs');
+ script.setAttribute("data-repo-id", 'R_kgDOGfXEXw');
+ script.setAttribute("data-category-id", 'DIC_kwDOGfXEX84CBHuf');
+ script.setAttribute("data-mapping", 'og:title');
+ script.setAttribute("data-input-position", 'bottom');
+ script.setAttribute("data-reactions-enabled", false);
+ script.setAttribute("data-theme", 'light');
+ script.setAttribute("data-lang", 'en');
+
+ script.src = "//giscus.app/client.js";
+ button.parentNode.replaceChild(script, button);
+ }
+ </script>
+ <button class="activator" onclick="giscus_load(this)">Show Comments from Github Discussions</button>
+
+ </div>
+
+ <footer>
+
+<ul>
+ <li><a href="https://github.com/m6w6/mdref">mdref-v3.0
+</a></li>
+ <li><a href="LICENSE">© 2013-2022 All rights reserved.</a></li>
+ <li>
+</li>
+</ul>
+
+ </footer>
+
+ <script src="index.js" defer></script>
+
+ </div>
+ </body>
+</html>
--- /dev/null
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ ★2. What is ion -
+ mdref
+ </title>
+ <meta property="og:title" content="ion/: Tutorial/:2. What is ion">
+ <meta name="viewport" content="width=1200, initial-scale=0.5">
+ <base href="/ext-ion/v0.1/">
+ <meta http-equiv="Content-Location" content="/ext-ion/v0.1/ion/: Tutorial/:2. What is ion">
+ <link rel="stylesheet" href="index.css">
+
+ <link rel="shortcut icon" href="/ext-ion/v0.1/favicon.ico">
+ </head>
+ <body>
+ <div class="page">
+
+<div class="sidebar">
+
+ <div class="edit">
+ <a href="https://github.com/awesomized/ext-ion/edit/master/ion.stub.php">Edit</a>
+ </div>
+
+
+ <ul>
+ <li>↰ <a href="./">Home</a>
+
+ <ul>
+ <li>
+
+ ↑ <a href="./ion">
+ ion
+ </a>
+ <ul>
+ <li>
+
+ ↑ <a href="./ion/: Tutorial">
+ ★ Tutorial
+ </a>
+ <ul>
+ <li>
+
+ ↻ <strong><a href="./ion/: Tutorial/:2. What is ion">★2. What is ion</a></strong>
+
+
+
+ </ul>
+
+ <li>↲ <a href="./ion/: Tutorial/:1. Getting started">★1. Getting started</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:3. Standard Datatypes">★3. Standard Datatypes</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:4. Special Datatypes">★4. Special Datatypes</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:5. Symbols, Tables and Catalogs">★5. Symbols, Tables and Catalogs</a></li>
+
+ </ul>
+
+ </li>
+ </ul>
+
+ </li>
+ </ul>
+</div>
+ <meta charset="utf-8"><h1>
+<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#">#</a>What Is Ion?</h1><p>Quoting the <a href="https://amzn.github.io/ion-docs/">official Ion documentation</a>:</p><p><strong>Amazon Ion</strong> is a <a href="ion/:%20Tutorial/:1.%20Getting%20started#Rich.type.system">richly-typed</a>, <a href="ion/:%20Tutorial/:1.%20Getting%20started#Self-describing">self-describing</a>, hierarchical data serialization format offering <a href="https://amzn.github.io/ion-docs/guides/why.html#dual-format-interoperability">interchangeable binary and text</a> representations. The <a href="https://amzn.github.io/ion-docs/docs/spec.html">text format</a> (a superset of <a href="http://json.org/">JSON</a>) is easy to read and author, supporting rapid prototyping.</p><p>The <a href="https://amzn.github.io/ion-docs/docs/binary.html">binary representation</a> is <a href="https://amzn.github.io/ion-docs/guides/why.html#read-optimized-binary-format">efficient to store, transmit, and skip-scan parse</a>.</p><p>The rich type system provides unambiguous semantics for longterm preservation of data which can survive multiple generations of software evolution.</p><p>Ion was built to address rapid development, decoupling, and efficiency challenges faced every day while engineering large-scale, service-oriented architectures.</p><h3 id="Some.simple.examples">Some simple examples<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Some.simple.examples">#</a>
+</h3><h4 id="Serialization:">Serialization:<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Serialization:">#</a>
+</h4><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br>ion\serialize</span><span style="color: inherit" class="keyword">([<br> </span><span style="color: inherit" class="string">"key" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="string">"value"</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="string">"more" </span><span style="color: inherit" class="keyword">=> [<br> </span><span style="color: inherit" class="string">"data" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="default">123<br> </span><span style="color: inherit" class="keyword">]<br>]);<br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h5 id="Output:">Output:<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Output:">#</a>
+</h5><pre><code><span style="color: inherit" class="html">
+{key:"value",more:{data:123}}<br></span>
+</code></pre><p>If you now think that this looks a lot like JSON, you're probably right, because Ion is a superset of JSON:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br>json_encode</span><span style="color: inherit" class="keyword">([<br> </span><span style="color: inherit" class="string">"key" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="string">"value"</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="string">"more" </span><span style="color: inherit" class="keyword">=> [<br> </span><span style="color: inherit" class="string">"data" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="default">123<br> </span><span style="color: inherit" class="keyword">]<br>]);<br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h5 id="Output:">Output:<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Output:">#</a>
+</h5><pre><code><span style="color: inherit" class="html">
+{"key":"value","more":{"data":123}}<br></span>
+</code></pre><p>So, all valid JSON is also valid Ion. Please refer to the <a href="https://amzn.github.io/ion-docs/docs/spec.html">official spec</a> to learn more about this topic.</p><h4 id="Unserialization:">Unserialization:<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Unserialization:">#</a>
+</h4><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br>var_representation</span><span style="color: inherit" class="keyword">(<br> </span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">'{key:"value",more:{data:123}}'</span><span style="color: inherit" class="keyword">)<br>);<br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h5 id="Output:">Output:<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Output:">#</a>
+</h5><pre><code><span style="color: inherit" class="html">
+[<br> 'key' => 'value',<br> 'more' => [<br> 'data' => 123,<br> ],<br>]<br></span>
+</code></pre><p>If you try the same with the JSON equivalent, you'll see that it's basically valid Ion, too:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br>var_representation</span><span style="color: inherit" class="keyword">(<br> </span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">'{"key":"value","more":{"data":123}}'</span><span style="color: inherit" class="keyword">)<br>);<br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h5 id="Output:">Output:<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Output:">#</a>
+</h5><pre><code><span style="color: inherit" class="html">
+[<br> 'key' => 'value',<br> 'more' => [<br> 'data' => 123,<br> ],<br>]<br></span>
+</code></pre><h3 id="Multiple.documents">Multiple documents<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Multiple.documents">#</a>
+</h3><p>Ion supports multiple sequences of documents within a single stream; consider the following:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br>var_representation</span><span style="color: inherit" class="keyword">(<br> </span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">'<br> {"key":"value","more":{"data":123}}<br> {"key":"value","more":{"data":456}}<br> '</span><span style="color: inherit" class="keyword">, new </span><span style="color: inherit" class="default">ion\Unserializer\PHP</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">multiSequence</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="default">true</span><span style="color: inherit" class="keyword">)<br> )<br>);<br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h4 id="Output:">Output:<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Output:">#</a>
+</h4><pre><code><span style="color: inherit" class="html">
+[<br> [<br> 'key' => 'value',<br> 'more' => [<br> 'data' => 123,<br> ],<br> ],<br> [<br> 'key' => 'value',<br> 'more' => [<br> 'data' => 456,<br> ],<br> ],<br>]<br></span>
+</code></pre><h3 id="Annotations">Annotations<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Annotations">#</a>
+</h3><p>Any Ion value can include one or more annotation symbols denoting the semantics of the content. This can be used to:</p><ul>
+<li>Annotate individual values with schema types, for validation purposes.</li>
+<li>Associate a higher-level datatype (e.g. a Java <em>class</em>) during serialization processes.</li>
+<li>Indicate the notation used within a <code>blob</code> or <code>clob</code> value.</li>
+<li>Apply other application semantics to a single value.</li>
+</ul><p>In the text format, type annotations are denoted by a non-<code><a href="https://php.net/manual/en/language.types.null">null</a></code> symbol token and <code><a href="https://php.net/manual/en/language.types.float">double</a></code>-colons preceding any value. Multiple annotations on the same value are separated by <code><a href="https://php.net/manual/en/language.types.float">double</a></code>-colons:</p><pre><code><span style="color: inherit" class="html">
+int32::12 // Suggests 32 bits as end-user type<br>degrees::'celsius'::100 // You can have multiple annotaions on a value<br>'my.custom.type' :: { x : 12 , y : -1 } // Gives a struct a user-defined type<br><br>{ field: some_annotation::value } // Field's name must precede annotations of its value<br><br>jpeg :: {{ ... }} // Indicates the blob contains jpeg data<br>bool :: null.int // A very misleading annotation on the integer null<br>'' :: 1 // An empty annotation<br>null.symbol :: 1 // ERROR: type annotation cannot be null <br></span>
+</code></pre><p>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).</p><p>It’s important to understand that annotations are symbol <em>tokens</em>, not symbol <em>values</em>. That means they do not have annotations themselves. In particular, the text <code>a::c</code> is a single value consisting of three textual tokens (a symbol, a <code><a href="https://php.net/manual/en/language.types.float">double</a></code>-colon, and another symbol); the first symbol token is an <em>annotation</em> on the value, and the second is the <em>content</em> of the value.</p><h4 id="System.Annotations">System Annotations<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#System.Annotations">#</a>
+</h4><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br><br></span><span style="color: inherit" class="keyword">foreach (</span><span style="color: inherit" class="default">ion\Symbol\System</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">cases</span><span style="color: inherit" class="keyword">() as </span><span style="color: inherit" class="default">$e</span><span style="color: inherit" class="keyword">) {<br> </span><span style="color: inherit" class="default">printf</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"%30s:: => %s\n"</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="default">$e</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">value</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="default">$e</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">name</span><span style="color: inherit" class="keyword">);<br>}<br><br></span><span style="color: inherit" class="comment">/*<br> $ion:: => Ion<br> $ion_1_0:: => Ivm_1_0<br> $ion_symbol_table:: => IonSymbolTable<br> name:: => Name<br> version:: => Version<br> imports:: => Imports<br> symbols:: => Symbols<br> max_id:: => MaxId<br> $ion_shared_symbol_table:: => SharedSymbolTable<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h4 id="PHP.Annotations">PHP Annotations<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#PHP.Annotations">#</a>
+</h4><p>There are two handful of annotations used by PHP, which are centralized in the <a href="ion/Symbol/PHP">ion\Symbol\PHP</a> enumeration:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br><br></span><span style="color: inherit" class="keyword">foreach (</span><span style="color: inherit" class="default">ion\Symbol\PHP</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">cases</span><span style="color: inherit" class="keyword">() as </span><span style="color: inherit" class="default">$e</span><span style="color: inherit" class="keyword">) {<br> </span><span style="color: inherit" class="default">printf</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"%3s:: => %s\n"</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="default">$e</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">value</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="default">$e</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">name</span><span style="color: inherit" class="keyword">);<br>}<br><br></span><span style="color: inherit" class="comment">/*<br> PHP:: => PHP<br> R:: => Reference<br> r:: => Backref<br> p:: => Property<br> o:: => Object<br> c:: => ClassObject<br> O:: => MagicObject<br> C:: => CustomObject<br> E:: => Enum<br> S:: => Serializable<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><hr><h2 id="Next.up">Next up<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Next.up">#</a>
+</h2><ul>
+<li>
+<a href="ion/:%20Tutorial/:3.%20Standard%20Datatypes">Standard Datatypes</a>
+</li>
+</ul>
+ <div class="comments">
+ <style>.giscus-frame {min-height: 16em;}</style>
+ <script>
+ function giscus_load(button) {
+ let script = document.createElement("script");
+ script.setAttribute("data-repo", 'awesomized/ext-ion');
+ script.setAttribute("data-category", 'Comments on Docs');
+ script.setAttribute("data-repo-id", 'R_kgDOGfXEXw');
+ script.setAttribute("data-category-id", 'DIC_kwDOGfXEX84CBHuf');
+ script.setAttribute("data-mapping", 'og:title');
+ script.setAttribute("data-input-position", 'bottom');
+ script.setAttribute("data-reactions-enabled", false);
+ script.setAttribute("data-theme", 'light');
+ script.setAttribute("data-lang", 'en');
+
+ script.src = "//giscus.app/client.js";
+ button.parentNode.replaceChild(script, button);
+ }
+ </script>
+ <button class="activator" onclick="giscus_load(this)">Show Comments from Github Discussions</button>
+
+ </div>
+
+ <footer>
+
+<ul>
+ <li><a href="https://github.com/m6w6/mdref">mdref-v3.0
+</a></li>
+ <li><a href="LICENSE">© 2013-2022 All rights reserved.</a></li>
+ <li>
+</li>
+</ul>
+
+ </footer>
+
+ <script src="index.js" defer></script>
+
+ </div>
+ </body>
+</html>
--- /dev/null
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ ★2. What is ion -
+ mdref
+ </title>
+ <meta property="og:title" content="ion/: Tutorial/:2. What is ion">
+ <meta name="viewport" content="width=1200, initial-scale=0.5">
+ <base href="/ext-ion/v0.1/">
+ <meta http-equiv="Content-Location" content="/ext-ion/v0.1/ion/: Tutorial/:2. What is ion">
+ <link rel="stylesheet" href="index.css">
+
+ <link rel="shortcut icon" href="/ext-ion/v0.1/favicon.ico">
+ </head>
+ <body>
+ <div class="page">
+
+<div class="sidebar">
+
+ <div class="edit">
+ <a href="https://github.com/awesomized/ext-ion/edit/master/ion.stub.php">Edit</a>
+ </div>
+
+
+ <ul>
+ <li>↰ <a href="./">Home</a>
+
+ <ul>
+ <li>
+
+ ↑ <a href="./ion">
+ ion
+ </a>
+ <ul>
+ <li>
+
+ ↑ <a href="./ion/: Tutorial">
+ ★ Tutorial
+ </a>
+ <ul>
+ <li>
+
+ ↻ <strong><a href="./ion/: Tutorial/:2. What is ion">★2. What is ion</a></strong>
+
+
+
+ </ul>
+
+ <li>↲ <a href="./ion/: Tutorial/:2. What is ion?">★2. What is ion?</a></li>
+
+ </ul>
+
+ </li>
+ </ul>
+
+ </li>
+ </ul>
+</div>
+ <meta charset="utf-8"><h2 id="What.Is.Ion.">What Is Ion?<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#What.Is.Ion.">#</a>
+</h2><p>Quoting the <a href="https://amzn.github.io/ion-docs/">official Ion documentation</a>:</p><blockquote>
+<p><strong>Amazon Ion</strong> is a <a href="https://amzn.github.io/ion-docs/guides/why.html#rich-type-system">richly-typed</a>, <a href="https://amzn.github.io/ion-docs/guides/why.html#self-describing">self-describing</a>, hierarchical data serialization format offering <a href="https://amzn.github.io/ion-docs/guides/why.html#dual-format-interoperability">interchangeable binary and text</a> representations. The <a href="https://amzn.github.io/ion-docs/docs/spec.html">text format</a> (a superset of <a href="http://json.org/">JSON</a>) is easy to read and author, supporting rapid prototyping. The <a href="https://amzn.github.io/ion-docs/docs/binary.html">binary representation</a> is <a href="https://amzn.github.io/ion-docs/guides/why.html#read-optimized-binary-format">efficient to store, transmit, and skip-scan parse</a>. The rich type system provides unambiguous semantics for <code><a href="https://php.net/manual/en/language.types.integer">long</a></code>-term preservation of data which can survive multiple generations of software evolution.</p>
+<p>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.</p>
+</blockquote><h3 id="Simple.serialization">Simple serialization<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Simple.serialization">#</a>
+</h3><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br></span><span style="color: inherit" class="keyword">echo </span><span style="color: inherit" class="default">ion\serialize</span><span style="color: inherit" class="keyword">([<br> </span><span style="color: inherit" class="string">"key" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="string">"value"</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="string">"more" </span><span style="color: inherit" class="keyword">=> [<br> </span><span style="color: inherit" class="string">"data" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="default">123<br> </span><span style="color: inherit" class="keyword">]<br>]);<br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h4 id="Output:">Output:<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Output:">#</a>
+</h4><pre><code><span style="color: inherit" class="html">
+{key:"value",more:{data:123}}<br></span>
+</code></pre><p>If you now think that this looks a lot like JSON, you're probably right, because Ion is a superset of JSON:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br></span><span style="color: inherit" class="keyword">echo </span><span style="color: inherit" class="default">json_encode</span><span style="color: inherit" class="keyword">([<br> </span><span style="color: inherit" class="string">"key" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="string">"value"</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="string">"more" </span><span style="color: inherit" class="keyword">=> [<br> </span><span style="color: inherit" class="string">"data" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="default">123<br> </span><span style="color: inherit" class="keyword">]<br>]);<br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h4 id="Output:">Output:<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Output:">#</a>
+</h4><pre><code><span style="color: inherit" class="html">
+{"key":"value","more":{"data":123}}<br></span>
+</code></pre><p>So, all valid JSON is also valid Ion. Please refer to the <a href="https://amzn.github.io/ion-docs/docs/spec.html">official spec</a> to learn more about this topic.</p><h3 id="Simple.unserialization">Simple unserialization<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Simple.unserialization">#</a>
+</h3><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br>var_representation</span><span style="color: inherit" class="keyword">(<br> </span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">'{key:"value",more:{data:123}}'</span><span style="color: inherit" class="keyword">)<br>);<br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h4 id="Output:">Output:<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Output:">#</a>
+</h4><pre><code><span style="color: inherit" class="html">
+[<br> 'key' => 'value',<br> 'more' => [<br> 'data' => 123,<br> ],<br>]<br></span>
+</code></pre><p>If you try the same with the JSON equivalent, you'll see that it's basically valid Ion, too:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br>var_representation</span><span style="color: inherit" class="keyword">(<br> </span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">'{"key":"value","more":{"data":123}}'</span><span style="color: inherit" class="keyword">)<br>);<br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h4 id="Output:">Output:<a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#Output:">#</a>
+</h4><pre><code><span style="color: inherit" class="html">
+[<br> 'key' => 'value',<br> 'more' => [<br> 'data' => 123,<br> ],<br>]<br></span>
+</code></pre><h3><a class="permalink" href="ion/:%20Tutorial/:2.%20What%20is%20ion#">#</a></h3>
+ <div class="comments">
+ <style>.giscus-frame {min-height: 16em;}</style>
+ <script>
+ function giscus_load(button) {
+ let script = document.createElement("script");
+ script.setAttribute("data-repo", 'awesomized/ext-ion');
+ script.setAttribute("data-category", 'Comments on Docs');
+ script.setAttribute("data-repo-id", 'R_kgDOGfXEXw');
+ script.setAttribute("data-category-id", 'DIC_kwDOGfXEX84CBHuf');
+ script.setAttribute("data-mapping", 'og:title');
+ script.setAttribute("data-input-position", 'bottom');
+ script.setAttribute("data-reactions-enabled", false);
+ script.setAttribute("data-theme", 'light');
+ script.setAttribute("data-lang", 'en');
+
+ script.src = "//giscus.app/client.js";
+ button.parentNode.replaceChild(script, button);
+ }
+ </script>
+ <button class="activator" onclick="giscus_load(this)">Show Comments from Github Discussions</button>
+
+ </div>
+
+ <footer>
+
+<ul>
+ <li><a href="https://github.com/m6w6/mdref">mdref-v3.0
+</a></li>
+ <li><a href="LICENSE">© 2013-2022 All rights reserved.</a></li>
+ <li>
+</li>
+</ul>
+
+ </footer>
+
+ <script src="index.js" defer></script>
+
+ </div>
+ </body>
+</html>
--- /dev/null
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ ★3. Datatypes -
+ mdref
+ </title>
+ <meta property="og:title" content="ion/: Tutorial/:3. Datatypes">
+ <meta name="viewport" content="width=1200, initial-scale=0.5">
+ <base href="/ext-ion/v0.1/">
+ <meta http-equiv="Content-Location" content="/ext-ion/v0.1/ion/: Tutorial/:3. Datatypes">
+ <link rel="stylesheet" href="index.css">
+
+ <link rel="shortcut icon" href="/ext-ion/v0.1/favicon.ico">
+ </head>
+ <body>
+ <div class="page">
+
+<div class="sidebar">
+
+ <div class="edit">
+ <a href="https://github.com/awesomized/ext-ion/edit/master/ion.stub.php">Edit</a>
+ </div>
+
+
+ <ul>
+ <li>↰ <a href="./">Home</a>
+
+ <ul>
+ <li>
+
+ ↑ <a href="./ion">
+ ion
+ </a>
+ <ul>
+ <li>
+
+ ↑ <a href="./ion/: Tutorial">
+ ★ Tutorial
+ </a>
+ <ul>
+ <li>
+
+ ↻ <strong><a href="./ion/: Tutorial/:3. Datatypes">★3. Datatypes</a></strong>
+
+
+
+ </ul>
+
+ <li>↲ <a href="./ion/: Tutorial/:1. Getting started">★1. Getting started</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:2. What is ion">★2. What is ion</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:3. Standard Datatypes">★3. Standard Datatypes</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:4. Special Datatypes">★4. Special Datatypes</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:4. Symbols, Tables and Catalogs">★4. Symbols, Tables and Catalogs</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:5. Symbols, Tables and Catalogs">★5. Symbols, Tables and Catalogs</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/Untitled">Untitled</a></li>
+
+ </ul>
+
+ </li>
+ </ul>
+
+ </li>
+ </ul>
+</div>
+ <meta charset="utf-8"><h1>
+<a class="permalink" href="ion/:%20Tutorial/:3.%20Datatypes#">#</a>Datatypes</h1><h2 id="Standard.datatypes">Standard datatypes<a class="permalink" href="ion/:%20Tutorial/:3.%20Datatypes#Standard.datatypes">#</a>
+</h2><p>ION supports many of PHP's data types:</p><h3 id="NULL">
+<code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><a class="permalink" href="ion/:%20Tutorial/:3.%20Datatypes#NULL">#</a>
+</h3><p>Additonally to the plain and simple <code>NULL</code>, ION can attach a type to <code>NULL</code> values.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br>$writer </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Writer\Stream\Writer</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">STDOUT</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeNull</span><span style="color: inherit" class="keyword">();<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeTypedNull</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\Type</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">Int</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeTypedNull</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\Type</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">String</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">flush</span><span style="color: inherit" class="keyword">();<br><br></span><span style="color: inherit" class="comment">/*<br> null null.int null.string<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h2 id="Special.datatypes">Special datatypes<a class="permalink" href="ion/:%20Tutorial/:3.%20Datatypes#Special.datatypes">#</a>
+</h2><p>There are a handful of data types treated in a specific way in PHP; consider the following examples:</p><h3 id="Deprecated.Serializable">Deprecated <code><a href="https://php.net/manual/en/class.serializable">Serializable</a></code><a class="permalink" href="ion/:%20Tutorial/:3.%20Datatypes#Deprecated.Serializable">#</a>
+</h3><blockquote>
+<p><em><strong>NOTE:</strong></em><br>
+The <em>interface</em> <code><a href="https://php.net/manual/en/class.serializable">Serializable</a></code> has been deprecated in 8.1 and should be replaced with magic serialize methods.</p>
+</blockquote><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br></span><span style="color: inherit" class="keyword">class </span><span style="color: inherit" class="default">srlzbl </span><span style="color: inherit" class="keyword">implements </span><span style="color: inherit" class="default">\Serializable </span><span style="color: inherit" class="keyword">{<br> private </span><span style="color: inherit" class="default">$data </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="string">"foo"</span><span style="color: inherit" class="keyword">;<br> public function </span><span style="color: inherit" class="default">serialize</span><span style="color: inherit" class="keyword">() { <br> return </span><span style="color: inherit" class="string">"bar"</span><span style="color: inherit" class="keyword">; <br> }<br> public function </span><span style="color: inherit" class="default">unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$data</span><span style="color: inherit" class="keyword">) { <br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">data </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">$data</span><span style="color: inherit" class="keyword">; <br> }<br>}<br><br></span><span style="color: inherit" class="default">$srlzbl </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">srlzbl</span><span style="color: inherit" class="keyword">;<br></span><span style="color: inherit" class="default">var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$srlzbl</span><span style="color: inherit" class="keyword">);<br><br></span><span style="color: inherit" class="default">$srlzd </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">ion\serialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$srlzbl</span><span style="color: inherit" class="keyword">);<br>echo </span><span style="color: inherit" class="default">$srlzd</span><span style="color: inherit" class="keyword">;<br><br></span><span style="color: inherit" class="comment">/*<br> object(srlzbl)#4 (1) {<br> ["data":"srlzbl":private]=><br> string(3) "foo"<br> }<br> <br> S::srlzbl::{{"bar"}}<br><br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>Everything as expected so far, <code><a href="https://php.net/manual/en/class.serializable">Serializable</a></code> return a <code><a href="https://php.net/manual/en/language.types.string">string</a></code>, but since it cannot indicate whether it's a valid UTF-8 <code><a href="https://php.net/manual/en/language.types.string">string</a></code>, a <a href="ion/Type#CLob">ion\Type::CLob</a> or <a href="ion/Type#BLob">ion\Type::BLob</a>, CLobs are assumed.</p><p>Unserialization does not offer any surprises, either:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php <br> <br>var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$srlzd</span><span style="color: inherit" class="keyword">));<br><br></span><span style="color: inherit" class="comment">/*<br> object(srlzbl)#4 (1) {<br> ["data":"srlzbl":private]=><br> string(3) "bar"<br> }<br><br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h3 id="Magic.__serialize">Magic __serialize<a class="permalink" href="ion/:%20Tutorial/:3.%20Datatypes#Magic.__serialize">#</a>
+</h3><p>Implementing serialization behavior with magic methods is the preferred way since 8.1:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br></span><span style="color: inherit" class="keyword">class </span><span style="color: inherit" class="default">magic </span><span style="color: inherit" class="keyword">{<br> private </span><span style="color: inherit" class="default">string $foo </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="string">"foo"</span><span style="color: inherit" class="keyword">;<br> function </span><span style="color: inherit" class="default">__serialize</span><span style="color: inherit" class="keyword">() : array {<br> return [</span><span style="color: inherit" class="string">"foo" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="string">"bar"</span><span style="color: inherit" class="keyword">];<br> }<br> function </span><span style="color: inherit" class="default">__unserialize</span><span style="color: inherit" class="keyword">(array </span><span style="color: inherit" class="default">$data</span><span style="color: inherit" class="keyword">) : </span><span style="color: inherit" class="default">void </span><span style="color: inherit" class="keyword">{<br> foreach (</span><span style="color: inherit" class="default">$data </span><span style="color: inherit" class="keyword">as </span><span style="color: inherit" class="default">$k </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="default">$v</span><span style="color: inherit" class="keyword">) <br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">$k </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">$v</span><span style="color: inherit" class="keyword">;<br> }<br>}<br><br></span><span style="color: inherit" class="default">$magic </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">magic</span><span style="color: inherit" class="keyword">;<br></span><span style="color: inherit" class="default">var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$magic</span><span style="color: inherit" class="keyword">);<br><br></span><span style="color: inherit" class="default">$srlzd </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">ion\serialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$magic</span><span style="color: inherit" class="keyword">);<br>echo </span><span style="color: inherit" class="default">$srlzd</span><span style="color: inherit" class="keyword">;<br><br></span><span style="color: inherit" class="comment">/*<br> object(magic)#6 (1) {<br> ["foo":"magic":private]=><br> string(3) "foo"<br> }<br><br> O::magic::{foo:"bar"}<br><br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>Again, unserialization yields the expected results:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br>var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$srlzd</span><span style="color: inherit" class="keyword">));<br><br></span><span style="color: inherit" class="comment">/*<br> object(magic)#7 (1) {<br> ["foo":"magic":private]=><br> string(3) "bar"<br> }<br><br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h3 id="Custom.serialize">Custom serialize<a class="permalink" href="ion/:%20Tutorial/:3.%20Datatypes#Custom.serialize">#</a>
+</h3><p>Customly serializable objects work like magic serializable objects, with custom names for the magic methods.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br></span><span style="color: inherit" class="keyword">class </span><span style="color: inherit" class="default">custom </span><span style="color: inherit" class="keyword">{<br> private array </span><span style="color: inherit" class="default">$data</span><span style="color: inherit" class="keyword">;<br> function </span><span style="color: inherit" class="default">init</span><span style="color: inherit" class="keyword">(array </span><span style="color: inherit" class="default">$data</span><span style="color: inherit" class="keyword">) : </span><span style="color: inherit" class="default">void </span><span style="color: inherit" class="keyword">{<br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">data </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">$data</span><span style="color: inherit" class="keyword">;<br> }<br> function </span><span style="color: inherit" class="default">export</span><span style="color: inherit" class="keyword">() : array {<br> return </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">data</span><span style="color: inherit" class="keyword">;<br> }<br>}<br><br></span><span style="color: inherit" class="default">$custom </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">custom</span><span style="color: inherit" class="keyword">;<br></span><span style="color: inherit" class="default">$custom</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">init</span><span style="color: inherit" class="keyword">([</span><span style="color: inherit" class="string">"foo" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="string">"bar"</span><span style="color: inherit" class="keyword">]);<br>echo </span><span style="color: inherit" class="default">$srlzd </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">ion\serialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$custom</span><span style="color: inherit" class="keyword">);<br><br></span><span style="color: inherit" class="comment">/*<br> c::custom::{data:p::custom::{foo:"bar"}}<br> <br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>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:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br>$srlzr </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Serializer\PHP</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">callCustomSerialize</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="string">"export"</span><span style="color: inherit" class="keyword">);<br>echo </span><span style="color: inherit" class="default">$srlzd </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">ion\serialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$custom</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="default">$srlzr</span><span style="color: inherit" class="keyword">);<br><br></span><span style="color: inherit" class="comment">/*<br> C::custom::{foo:"bar"}<br><br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>Note how this output compares to the output of the standard magic serializable object.</p><p>Unserialization works as used to, except sepcifying thwe custom unserialization method to call:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br>$unsrlzr </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Unserializer\PHP</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">callCustomUnserialize</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="string">"init"</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$srlzd</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="default">$unsrlzr</span><span style="color: inherit" class="keyword">));<br><br></span><span style="color: inherit" class="comment">/*<br> object(custom)#10 (1) {<br> ["data":"custom":private]=><br> array(1) {<br> ["foo"]=><br> string(3) "bar"<br> }<br> }<br><br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h3 id="Decimal">Decimal<a class="permalink" href="ion/:%20Tutorial/:3.%20Datatypes#Decimal">#</a>
+</h3><h3 id="LOB">LOB<a class="permalink" href="ion/:%20Tutorial/:3.%20Datatypes#LOB">#</a>
+</h3><h3 id="Symbol">Symbol<a class="permalink" href="ion/:%20Tutorial/:3.%20Datatypes#Symbol">#</a>
+</h3><h3 id="Timestamp">Timestamp<a class="permalink" href="ion/:%20Tutorial/:3.%20Datatypes#Timestamp">#</a>
+</h3><p>Instances of <a href="ion/Timestamp">ion\Timestamp</a> are really just plain <code><a href="https://php.net/manual/en/class.datetime">\DateTime</a></code> objects augmented with <code><a href="https://php.net/manual/en/class.stringable">Stringable</a></code> and ION specific formatting.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br></span><span style="color: inherit" class="keyword">new </span><span style="color: inherit" class="default">ion\Timestamp</span><span style="color: inherit" class="keyword">(<br> </span><span style="color: inherit" class="default">precision</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="default">ion\Timestamp\Precision</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">FracTZ</span><span style="color: inherit" class="keyword">,<br>) <br> <br> </span><span style="color: inherit" class="comment">// 2022-02-25T16:11:54.118+00:00<br> <br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br></span><span style="color: inherit" class="keyword">new </span><span style="color: inherit" class="default">ion\Timestamp</span><span style="color: inherit" class="keyword">(<br> </span><span style="color: inherit" class="default">precision</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="default">ion\Timestamp\Precision</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">Day<br></span><span style="color: inherit" class="keyword">) <br> <br> </span><span style="color: inherit" class="comment">// 2022-02-25T<br> <br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br></span><span style="color: inherit" class="keyword">new </span><span style="color: inherit" class="default">ion\Timestamp</span><span style="color: inherit" class="keyword">(<br> </span><span style="color: inherit" class="default">precision</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="default">ion\Timestamp\Precision</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">MinTZ</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="default">format</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="default">ion\Timestamp\Format</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">Min</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="default">datetime</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="string">"2020-03-15T12:34"</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="default">timezone</span><span style="color: inherit" class="keyword">: new </span><span style="color: inherit" class="default">DateTimeZone</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"Europe/Vienna"</span><span style="color: inherit" class="keyword">)<br>) <br> <br> </span><span style="color: inherit" class="comment">// 2020-03-15T12:34+01:00<br> <br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre>
+ <div class="comments">
+ <style>.giscus-frame {min-height: 16em;}</style>
+ <script>
+ function giscus_load(button) {
+ let script = document.createElement("script");
+ script.setAttribute("data-repo", 'awesomized/ext-ion');
+ script.setAttribute("data-category", 'Comments on Docs');
+ script.setAttribute("data-repo-id", 'R_kgDOGfXEXw');
+ script.setAttribute("data-category-id", 'DIC_kwDOGfXEX84CBHuf');
+ script.setAttribute("data-mapping", 'og:title');
+ script.setAttribute("data-input-position", 'bottom');
+ script.setAttribute("data-reactions-enabled", false);
+ script.setAttribute("data-theme", 'light');
+ script.setAttribute("data-lang", 'en');
+
+ script.src = "//giscus.app/client.js";
+ button.parentNode.replaceChild(script, button);
+ }
+ </script>
+ <button class="activator" onclick="giscus_load(this)">Show Comments from Github Discussions</button>
+
+ </div>
+
+ <footer>
+
+<ul>
+ <li><a href="https://github.com/m6w6/mdref">mdref-v3.0
+</a></li>
+ <li><a href="LICENSE">© 2013-2022 All rights reserved.</a></li>
+ <li>
+</li>
+</ul>
+
+ </footer>
+
+ <script src="index.js" defer></script>
+
+ </div>
+ </body>
+</html>
--- /dev/null
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ ★3. Standard Datatypes -
+ mdref
+ </title>
+ <meta property="og:title" content="ion/: Tutorial/:3. Standard Datatypes">
+ <meta name="viewport" content="width=1200, initial-scale=0.5">
+ <base href="/ext-ion/v0.1/">
+ <meta http-equiv="Content-Location" content="/ext-ion/v0.1/ion/: Tutorial/:3. Standard Datatypes">
+ <link rel="stylesheet" href="index.css">
+
+ <link rel="shortcut icon" href="/ext-ion/v0.1/favicon.ico">
+ </head>
+ <body>
+ <div class="page">
+
+<div class="sidebar">
+
+ <div class="edit">
+ <a href="https://github.com/awesomized/ext-ion/edit/master/ion.stub.php">Edit</a>
+ </div>
+
+
+ <ul>
+ <li>↰ <a href="./">Home</a>
+
+ <ul>
+ <li>
+
+ ↑ <a href="./ion">
+ ion
+ </a>
+ <ul>
+ <li>
+
+ ↑ <a href="./ion/: Tutorial">
+ ★ Tutorial
+ </a>
+ <ul>
+ <li>
+
+ ↻ <strong><a href="./ion/: Tutorial/:3. Standard Datatypes">★3. Standard Datatypes</a></strong>
+
+
+
+ </ul>
+
+ <li>↲ <a href="./ion/: Tutorial/:1. Getting started">★1. Getting started</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:2. What is ion">★2. What is ion</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:4. Special Datatypes">★4. Special Datatypes</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:5. Symbols, Tables and Catalogs">★5. Symbols, Tables and Catalogs</a></li>
+
+ </ul>
+
+ </li>
+ </ul>
+
+ </li>
+ </ul>
+</div>
+ <meta charset="utf-8"><h1>
+<a class="permalink" href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#">#</a>Standard Datatypes</h1><p>ION supports many of PHP's data types:</p><h2 id="Nulls">Nulls<a class="permalink" href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#Nulls">#</a>
+</h2><p>Additonally to the plain and simple <code>NULL</code>, ION can attach a type to <code>NULL</code> values.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br>$writer </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Writer\Stream\Writer</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">STDOUT</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeNull</span><span style="color: inherit" class="keyword">();<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeTypedNull</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\Type</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">Int</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeTypedNull</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\Type</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">String</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">flush</span><span style="color: inherit" class="keyword">();<br><br></span><span style="color: inherit" class="comment">/*<br> null<br> null.int<br> null.string<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h2 id="Booleans">Booleans<a class="permalink" href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#Booleans">#</a>
+</h2><p>The <code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> type does not need a lot of explanation:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br><br>$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeBool</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">true</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeBool</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">false</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">flush</span><span style="color: inherit" class="keyword">();<br><br></span><span style="color: inherit" class="comment">/*<br> true<br> false<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h2 id="Integers">Integers<a class="permalink" href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#Integers">#</a>
+</h2><p>The <code><a href="https://php.net/manual/en/language.types.integer">int</a></code> type comprises signed integers of arbitrary size.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br>$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeInt</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">123</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeInt</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"12345678901234567890"</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">flush</span><span style="color: inherit" class="keyword">();<br><br></span><span style="color: inherit" class="comment">/*<br> 123<br> 12345678901234567890<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>In ION-Text, underscores are allowed to separate digits:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br>$reader </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Reader\Buffer\Reader</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"-123_456_789"</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">$reader</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">next</span><span style="color: inherit" class="keyword">();<br></span><span style="color: inherit" class="default">var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$reader</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">getType</span><span style="color: inherit" class="keyword">());<br></span><span style="color: inherit" class="default">var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$reader</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">readInt</span><span style="color: inherit" class="keyword">());<br><br></span><span style="color: inherit" class="comment">/*<br> enum(ion\Type::Int)<br> int(-123456789)<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>Hexadecimal as well as binary notation are supported, too:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br><br>$reader </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Reader\Buffer\Reader</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"0xdead_beef"</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">$reader</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">next</span><span style="color: inherit" class="keyword">();<br></span><span style="color: inherit" class="default">var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$reader</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">readInt</span><span style="color: inherit" class="keyword">());<br><br></span><span style="color: inherit" class="comment">/*<br> int(3735928559)<br>*/<br><br></span><span style="color: inherit" class="default">$reader </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Reader\Buffer\Reader</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"0b10000100_11001001"</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">$reader</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">next</span><span style="color: inherit" class="keyword">();<br></span><span style="color: inherit" class="default">var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$reader</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">readInt</span><span style="color: inherit" class="keyword">());<br><br></span><span style="color: inherit" class="comment">/*<br> int(33993)<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h2 id="Reals">Reals<a class="permalink" href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#Reals">#</a>
+</h2><p>Ion supports both binary and lossless decimal encodings of <code><a href="https://php.net/manual/en/language.types.float">real</a></code> numbers as, respectively, types <code>float</code> and <code>decimal</code>. In the text format, <code>float</code> values are denoted much like the decimal formats in C or Java; <code>decimal</code> values use <code>d</code> instead of <code>e</code> to start the exponent.</p><p>Reals without an exponent are treated as decimal. As with JSON, extra leading zeros are not allowed. Digits may be separated with an underscore.</p><h3 id="Floats">Floats<a class="permalink" href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#Floats">#</a>
+</h3><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br><br>var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\serialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">0.123</span><span style="color: inherit" class="keyword">));<br><br></span><span style="color: inherit" class="comment">/*<br> string(25) "0.12299999999999999822e+0"<br>*/<br><br></span><span style="color: inherit" class="default">var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"[0.123e, 123e-3]"</span><span style="color: inherit" class="keyword">));<br><br></span><span style="color: inherit" class="comment">/*<br> array(2) {<br> [0]=><br> float(0.123)<br> [1]=><br> float(0.123)<br> }<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h3 id="Decimals">Decimals<a class="permalink" href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#Decimals">#</a>
+</h3><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br><br>var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\serialize</span><span style="color: inherit" class="keyword">(new </span><span style="color: inherit" class="default">ion\Decimal</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"0.123"</span><span style="color: inherit" class="keyword">)));<br><br></span><span style="color: inherit" class="comment">/*<br> string(5) "0.123"<br>*/<br><br></span><span style="color: inherit" class="default">var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"[0.123d0, 123d-3]"</span><span style="color: inherit" class="keyword">));<br><br></span><span style="color: inherit" class="comment">/*<br> array(2) {<br> [0]=><br> object(ion\Decimal)#8 (2) {<br> ["number"]=><br> string(5) "0.123"<br> // ...<br> }<br> [1]=><br> object(ion\Decimal)#11 (2) {<br> ["number"]=><br> string(5) "0.123"<br> // ...<br> }<br> }<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h2 id="Strings">Strings<a class="permalink" href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#Strings">#</a>
+</h2><p>Ion strings are Unicode character sequences of arbitrary length.</p><p>In the text format, strings are delimited by <code><a href="https://php.net/manual/en/language.types.float">double</a></code>-quotes and follow common backslash-escape conventions (see <a href="https://amzn.github.io/ion-docs/docs/spec.html#escapess">official spec</a>). The binary format always uses UTF-8 encoding.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br><br>ion\serialize</span><span style="color: inherit" class="keyword">([<br> </span><span style="color: inherit" class="string">"abc"</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="string">"new<br>line"<br></span><span style="color: inherit" class="keyword">]);<br><br></span><span style="color: inherit" class="comment">/*<br> ["abc", "new\nline"]<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h3 id="Long.Strings">Long Strings<a class="permalink" href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#Long.Strings">#</a>
+</h3><p>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 <code><a href="https://php.net/manual/en/language.types.string">string</a></code>. In addition, any number of adjacent triple-quoted strings are concatenated into a single value.</p><p>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 <code><a href="https://php.net/manual/en/language.types.integer">long</a></code> strings.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br>var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"<br>'''<br> here are <br> several new<br> lines<br>'''<br>"</span><span style="color: inherit" class="keyword">));<br><br></span><span style="color: inherit" class="comment">/*<br>string(35) "<br> here are <br> several new<br> lines<br>"<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h2 id="Containers">Containers<a class="permalink" href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#Containers">#</a>
+</h2><p>Ion defines three container types: structures, lists, and S-expressions. These types are defined recursively and may contain values of any Ion type.</p><h3 id="Lists">Lists<a class="permalink" href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#Lists">#</a>
+</h3><p>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.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br><br>ion\serialize</span><span style="color: inherit" class="keyword">([</span><span style="color: inherit" class="default">1</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="string">"yes"</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="default">null</span><span style="color: inherit" class="keyword">]);<br><br></span><span style="color: inherit" class="comment">/*<br> [1,"yes",null]<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h3 id="Structures">Structures<a class="permalink" href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#Structures">#</a>
+</h3><p>Structures are <em>unordered</em> collections of name/value pairs. The names are symbol tokens, and the values are unrestricted. Each name/value pair is called a field.</p><p>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.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br><br>ion\serialize</span><span style="color: inherit" class="keyword">([<br> </span><span style="color: inherit" class="string">"outlaw"</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="string">"key" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="string">"value"</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="string">"obj" </span><span style="color: inherit" class="keyword">=> (object)[</span><span style="color: inherit" class="string">"key" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="string">"value"</span><span style="color: inherit" class="keyword">]<br>]);<br><br></span><span style="color: inherit" class="comment">/*<br> {'0':"outlaw",key:"value",obj:o::{key:"value"}}<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br><br>var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(<br> </span><span style="color: inherit" class="string">'{\'0\':"outlaw",key:"value",obj:o::{key:"value"}}'<br></span><span style="color: inherit" class="keyword">));<br><br></span><span style="color: inherit" class="comment">/*<br> array(3) {<br> [0]=><br> string(6) "outlaw"<br> ["key"]=><br> string(5) "value"<br> ["obj"]=><br> object(stdClass)#10 (1) {<br> ["key"]=><br> string(5) "value"<br> }<br> }<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><hr><h2 id="Next.up">Next up<a class="permalink" href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#Next.up">#</a>
+</h2><ul>
+<li>
+<a href="ion/:%20Tutorial/:4.%20Special%20Datatypes">Special Datatypes</a>
+</li>
+</ul>
+ <div class="comments">
+ <style>.giscus-frame {min-height: 16em;}</style>
+ <script>
+ function giscus_load(button) {
+ let script = document.createElement("script");
+ script.setAttribute("data-repo", 'awesomized/ext-ion');
+ script.setAttribute("data-category", 'Comments on Docs');
+ script.setAttribute("data-repo-id", 'R_kgDOGfXEXw');
+ script.setAttribute("data-category-id", 'DIC_kwDOGfXEX84CBHuf');
+ script.setAttribute("data-mapping", 'og:title');
+ script.setAttribute("data-input-position", 'bottom');
+ script.setAttribute("data-reactions-enabled", false);
+ script.setAttribute("data-theme", 'light');
+ script.setAttribute("data-lang", 'en');
+
+ script.src = "//giscus.app/client.js";
+ button.parentNode.replaceChild(script, button);
+ }
+ </script>
+ <button class="activator" onclick="giscus_load(this)">Show Comments from Github Discussions</button>
+
+ </div>
+
+ <footer>
+
+<ul>
+ <li><a href="https://github.com/m6w6/mdref">mdref-v3.0
+</a></li>
+ <li><a href="LICENSE">© 2013-2022 All rights reserved.</a></li>
+ <li>
+</li>
+</ul>
+
+ </footer>
+
+ <script src="index.js" defer></script>
+
+ </div>
+ </body>
+</html>
--- /dev/null
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ ★4. Special Datatypes -
+ mdref
+ </title>
+ <meta property="og:title" content="ion/: Tutorial/:4. Special Datatypes">
+ <meta name="viewport" content="width=1200, initial-scale=0.5">
+ <base href="/ext-ion/v0.1/">
+ <meta http-equiv="Content-Location" content="/ext-ion/v0.1/ion/: Tutorial/:4. Special Datatypes">
+ <link rel="stylesheet" href="index.css">
+
+ <link rel="shortcut icon" href="/ext-ion/v0.1/favicon.ico">
+ </head>
+ <body>
+ <div class="page">
+
+<div class="sidebar">
+
+ <div class="edit">
+ <a href="https://github.com/awesomized/ext-ion/edit/master/ion.stub.php">Edit</a>
+ </div>
+
+
+ <ul>
+ <li>↰ <a href="./">Home</a>
+
+ <ul>
+ <li>
+
+ ↑ <a href="./ion">
+ ion
+ </a>
+ <ul>
+ <li>
+
+ ↑ <a href="./ion/: Tutorial">
+ ★ Tutorial
+ </a>
+ <ul>
+ <li>
+
+ ↻ <strong><a href="./ion/: Tutorial/:4. Special Datatypes">★4. Special Datatypes</a></strong>
+
+
+
+ </ul>
+
+ <li>↲ <a href="./ion/: Tutorial/:1. Getting started">★1. Getting started</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:2. What is ion">★2. What is ion</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:3. Standard Datatypes">★3. Standard Datatypes</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:5. Symbols, Tables and Catalogs">★5. Symbols, Tables and Catalogs</a></li>
+
+ </ul>
+
+ </li>
+ </ul>
+
+ </li>
+ </ul>
+</div>
+ <meta charset="utf-8"><h1>
+<a class="permalink" href="ion/:%20Tutorial/:4.%20Special%20Datatypes#">#</a>Special Datatypes</h1><p>There are a handful of data types treated in a specific way in PHP; consider the following examples:</p><h2 id="Symbols">Symbols<a class="permalink" href="ion/:%20Tutorial/:4.%20Special%20Datatypes#Symbols">#</a>
+</h2><p>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.</p><p>In the text format, symbols are delimited by single-quotes and use the same <a href="https://amzn.github.io/ion-docs/docs/spec.html#escapes">escape characters</a>.</p><p>See <a href="https://amzn.github.io/ion-docs/docs/symbols.html">Ion Symbols</a> for more details about symbol representations and symbol tables, and our section on <a href="ion/:%20Tutorial/:5.%20Symbols,%20Tables%20and%20Catalogs">Symbols, Tables and Catalogs</a> for a distilled read.</p><h2 id="Decimals">Decimals<a class="permalink" href="ion/:%20Tutorial/:4.%20Special%20Datatypes#Decimals">#</a>
+</h2><p>See the <a href="ion/:%20Tutorial/:3.%20Standard%20Datatypes#Reals">section on reals</a> for an introduction.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br>$d </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Decimal</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">123</span><span style="color: inherit" class="keyword">);<br>echo </span><span style="color: inherit" class="default">ion\serialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$d</span><span style="color: inherit" class="keyword">), </span><span style="color: inherit" class="string">" = "</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="default">$d</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">isInt</span><span style="color: inherit" class="keyword">() ? </span><span style="color: inherit" class="string">"int" </span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="string">"noint"</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="string">"\n"</span><span style="color: inherit" class="keyword">;<br></span><span style="color: inherit" class="comment">// 123d0 = int<br><br></span><span style="color: inherit" class="default">$d </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Decimal</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"123.123"</span><span style="color: inherit" class="keyword">);<br>echo </span><span style="color: inherit" class="default">ion\serialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$d</span><span style="color: inherit" class="keyword">), </span><span style="color: inherit" class="string">" = "</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="default">$d</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">isInt</span><span style="color: inherit" class="keyword">() ? </span><span style="color: inherit" class="string">"int" </span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="string">"noint" </span><span style="color: inherit" class="keyword">,</span><span style="color: inherit" class="string">"\n"</span><span style="color: inherit" class="keyword">;<br></span><span style="color: inherit" class="comment">// 123.123 = noint<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>See the <a href="https://amzn.github.io/ion-docs/docs/spec.html#real-numbers">official ION spec about real numbers</a> and also <a href="https://amzn.github.io/ion-docs/docs/float.html">Ion Float</a> and <a href="https://amzn.github.io/ion-docs/docs/decimal.html">Ion Decimals</a> for more notes.</p><h2 id="LOBs">LOBs<a class="permalink" href="ion/:%20Tutorial/:4.%20Special%20Datatypes#LOBs">#</a>
+</h2><h3 id="BLob">BLob<a class="permalink" href="ion/:%20Tutorial/:4.%20Special%20Datatypes#BLob">#</a>
+</h3><p>The <code>blob</code> 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.</p><p>In the text format, <code>blob</code> values are denoted as <a href="https://tools.ietf.org/html/rfc4648">RFC 4648</a>-compliant <a href="http://en.wikipedia.org/wiki/Base64">Base64</a> text within two pairs of curly braces.</p><pre><code><span style="color: inherit" class="html">
+{{ dHdvIHBhZGRpbmcgY2hhcmFjdGVycw== }}<br></span>
+</code></pre><h3 id="CLob">CLob<a class="permalink" href="ion/:%20Tutorial/:4.%20Special%20Datatypes#CLob">#</a>
+</h3><p>The <code>clob</code> type is similar to <code>blob</code> 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.</p><pre><code><span style="color: inherit" class="html">
+{{ "This is a CLOB of text." }}<br></span>
+</code></pre><p>See the official ION specification on <a href="https://amzn.github.io/ion-docs/docs/spec.html#blob">Blobs</a> and <a href="https://amzn.github.io/ion-docs/docs/spec.html#clob">Clobs</a>.</p><h2 id="Timestamps">Timestamps<a class="permalink" href="ion/:%20Tutorial/:4.%20Special%20Datatypes#Timestamps">#</a>
+</h2><p>Timestamps represent a specific moment in time, always include a local offset, and are capable of arbitrary precision.</p><p>Instances of <a href="ion/Timestamp">ion\Timestamp</a> are really just plain <code><a href="https://php.net/manual/en/class.datetime">\DateTime</a></code> objects augmented with <code><a href="https://php.net/manual/en/class.stringable">Stringable</a></code> and ION specific formatting.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br></span><span style="color: inherit" class="keyword">new </span><span style="color: inherit" class="default">ion\Timestamp</span><span style="color: inherit" class="keyword">(<br> </span><span style="color: inherit" class="default">precision</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="default">ion\Timestamp\Precision</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">FracTZ</span><span style="color: inherit" class="keyword">,<br>) <br> <br> </span><span style="color: inherit" class="comment">// 2022-02-25T16:11:54.118+00:00<br> <br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br></span><span style="color: inherit" class="keyword">new </span><span style="color: inherit" class="default">ion\Timestamp</span><span style="color: inherit" class="keyword">(<br> </span><span style="color: inherit" class="default">precision</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="default">ion\Timestamp\Precision</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">Day<br></span><span style="color: inherit" class="keyword">) <br> <br> </span><span style="color: inherit" class="comment">// 2022-02-25T<br> <br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?=<br></span><span style="color: inherit" class="keyword">new </span><span style="color: inherit" class="default">ion\Timestamp</span><span style="color: inherit" class="keyword">(<br> </span><span style="color: inherit" class="default">precision</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="default">ion\Timestamp\Precision</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">MinTZ</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="default">format</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="default">ion\Timestamp\Format</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">Min</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="default">datetime</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="string">"2020-03-15T12:34"</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="default">timezone</span><span style="color: inherit" class="keyword">: new </span><span style="color: inherit" class="default">DateTimeZone</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"Europe/Vienna"</span><span style="color: inherit" class="keyword">)<br>) <br> <br> </span><span style="color: inherit" class="comment">// 2020-03-15T12:34+01:00<br> <br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>See also the <a href="https://amzn.github.io/ion-docs/docs/spec.html#timestamp">official ION Timestamp specification</a>.</p><h2 id="Special.PHP.Objects">Special PHP Objects<a class="permalink" href="ion/:%20Tutorial/:4.%20Special%20Datatypes#Special.PHP.Objects">#</a>
+</h2><h3 id="Deprecated.Serializable:">Deprecated Serializable:<a class="permalink" href="ion/:%20Tutorial/:4.%20Special%20Datatypes#Deprecated.Serializable:">#</a>
+</h3><blockquote>
+<p><em><strong>NOTE:</strong></em><br>
+The <em>interface</em> <code><a href="https://php.net/manual/en/class.serializable">Serializable</a></code> has been deprecated in 8.1 and should be replaced with magic serialize methods.</p>
+</blockquote><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br></span><span style="color: inherit" class="keyword">class </span><span style="color: inherit" class="default">srlzbl </span><span style="color: inherit" class="keyword">implements </span><span style="color: inherit" class="default">\Serializable </span><span style="color: inherit" class="keyword">{<br> private </span><span style="color: inherit" class="default">$data </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="string">"foo"</span><span style="color: inherit" class="keyword">;<br> public function </span><span style="color: inherit" class="default">serialize</span><span style="color: inherit" class="keyword">() { <br> return </span><span style="color: inherit" class="string">"bar"</span><span style="color: inherit" class="keyword">; <br> }<br> public function </span><span style="color: inherit" class="default">unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$data</span><span style="color: inherit" class="keyword">) { <br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">data </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">$data</span><span style="color: inherit" class="keyword">; <br> }<br>}<br><br></span><span style="color: inherit" class="default">$srlzbl </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">srlzbl</span><span style="color: inherit" class="keyword">;<br></span><span style="color: inherit" class="default">var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$srlzbl</span><span style="color: inherit" class="keyword">);<br><br></span><span style="color: inherit" class="default">$srlzd </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">ion\serialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$srlzbl</span><span style="color: inherit" class="keyword">);<br>echo </span><span style="color: inherit" class="default">$srlzd</span><span style="color: inherit" class="keyword">;<br><br></span><span style="color: inherit" class="comment">/*<br> object(srlzbl)#4 (1) {<br> ["data":"srlzbl":private]=><br> string(3) "foo"<br> }<br> <br> S::srlzbl::{{"bar"}}<br><br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>Everything as expected so far, <code><a href="https://php.net/manual/en/class.serializable">Serializable</a></code> return a <code><a href="https://php.net/manual/en/language.types.string">string</a></code>, but since they cannot indicate whether it's a valid UTF-8 <code><a href="https://php.net/manual/en/language.types.string">string</a></code>, a <a href="ion/Type#CLob">ion\Type::CLob</a> or <a href="ion/Type#BLob">ion\Type::BLob</a>, CLobs are assumed.</p><p>Unserialization does not offer any surprises, either:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php <br> <br>var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$srlzd</span><span style="color: inherit" class="keyword">));<br><br></span><span style="color: inherit" class="comment">/*<br> object(srlzbl)#4 (1) {<br> ["data":"srlzbl":private]=><br> string(3) "bar"<br> }<br><br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h3 id="Magic.__serialize:">Magic __serialize:<a class="permalink" href="ion/:%20Tutorial/:4.%20Special%20Datatypes#Magic.__serialize:">#</a>
+</h3><p>Implementing serialization behavior with magic methods is the preferred way since 8.1:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br></span><span style="color: inherit" class="keyword">class </span><span style="color: inherit" class="default">magic </span><span style="color: inherit" class="keyword">{<br> private </span><span style="color: inherit" class="default">string $foo </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="string">"foo"</span><span style="color: inherit" class="keyword">;<br> function </span><span style="color: inherit" class="default">__serialize</span><span style="color: inherit" class="keyword">() : array {<br> return [</span><span style="color: inherit" class="string">"foo" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="string">"bar"</span><span style="color: inherit" class="keyword">];<br> }<br> function </span><span style="color: inherit" class="default">__unserialize</span><span style="color: inherit" class="keyword">(array </span><span style="color: inherit" class="default">$data</span><span style="color: inherit" class="keyword">) : </span><span style="color: inherit" class="default">void </span><span style="color: inherit" class="keyword">{<br> foreach (</span><span style="color: inherit" class="default">$data </span><span style="color: inherit" class="keyword">as </span><span style="color: inherit" class="default">$k </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="default">$v</span><span style="color: inherit" class="keyword">) <br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">$k </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">$v</span><span style="color: inherit" class="keyword">;<br> }<br>}<br><br></span><span style="color: inherit" class="default">$magic </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">magic</span><span style="color: inherit" class="keyword">;<br></span><span style="color: inherit" class="default">var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$magic</span><span style="color: inherit" class="keyword">);<br><br></span><span style="color: inherit" class="default">$srlzd </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">ion\serialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$magic</span><span style="color: inherit" class="keyword">);<br>echo </span><span style="color: inherit" class="default">$srlzd</span><span style="color: inherit" class="keyword">;<br><br></span><span style="color: inherit" class="comment">/*<br> object(magic)#6 (1) {<br> ["foo":"magic":private]=><br> string(3) "foo"<br> }<br><br> O::magic::{foo:"bar"}<br><br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>Again, unserialization yields the expected results:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br>var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$srlzd</span><span style="color: inherit" class="keyword">));<br><br></span><span style="color: inherit" class="comment">/*<br> object(magic)#7 (1) {<br> ["foo":"magic":private]=><br> string(3) "bar"<br> }<br><br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h3 id="Custom.serialize:">Custom serialize:<a class="permalink" href="ion/:%20Tutorial/:4.%20Special%20Datatypes#Custom.serialize:">#</a>
+</h3><p>Customly serializable objects work like magic serializable objects, with custom names for the magic methods.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br></span><span style="color: inherit" class="keyword">class </span><span style="color: inherit" class="default">custom </span><span style="color: inherit" class="keyword">{<br> private array </span><span style="color: inherit" class="default">$data</span><span style="color: inherit" class="keyword">;<br> function </span><span style="color: inherit" class="default">init</span><span style="color: inherit" class="keyword">(array </span><span style="color: inherit" class="default">$data</span><span style="color: inherit" class="keyword">) : </span><span style="color: inherit" class="default">void </span><span style="color: inherit" class="keyword">{<br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">data </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">$data</span><span style="color: inherit" class="keyword">;<br> }<br> function </span><span style="color: inherit" class="default">export</span><span style="color: inherit" class="keyword">() : array {<br> return </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">data</span><span style="color: inherit" class="keyword">;<br> }<br>}<br><br></span><span style="color: inherit" class="default">$custom </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">custom</span><span style="color: inherit" class="keyword">;<br></span><span style="color: inherit" class="default">$custom</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">init</span><span style="color: inherit" class="keyword">([</span><span style="color: inherit" class="string">"foo" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="string">"bar"</span><span style="color: inherit" class="keyword">]);<br>echo </span><span style="color: inherit" class="default">$srlzd </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">ion\serialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$custom</span><span style="color: inherit" class="keyword">);<br><br></span><span style="color: inherit" class="comment">/*<br> c::custom::{data:p::custom::{foo:"bar"}}<br> <br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>The above is actually the result of serializing a standard <em>class</em> 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:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br>$srlzr </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Serializer\PHP</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">callCustomSerialize</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="string">"export"</span><span style="color: inherit" class="keyword">);<br>echo </span><span style="color: inherit" class="default">$srlzd </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">ion\serialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$custom</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="default">$srlzr</span><span style="color: inherit" class="keyword">);<br><br></span><span style="color: inherit" class="comment">/*<br> C::custom::{foo:"bar"}<br><br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>Note how this output compares to the output of the standard magic serializable object.</p><p>Unserialization works as used to, except sepcifying thwe custom unserialization method to call:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br>$unsrlzr </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Unserializer\PHP</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">callCustomUnserialize</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="string">"init"</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$srlzd</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="default">$unsrlzr</span><span style="color: inherit" class="keyword">));<br><br></span><span style="color: inherit" class="comment">/*<br> object(custom)#10 (1) {<br> ["data":"custom":private]=><br> array(1) {<br> ["foo"]=><br> string(3) "bar"<br> }<br> }<br><br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h2 id="S-Expressions">S-Expressions<a class="permalink" href="ion/:%20Tutorial/:4.%20Special%20Datatypes#S-Expressions">#</a>
+</h2><p>An S-expression (or <a href="https://en.wikipedia.org/wiki/S-expression">symbolic expression</a>) 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.</p><p>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.</p><pre><code><span style="color: inherit" class="html">
+null.sexp // A null S-expression value<br>() // An empty expression value<br>(cons 1 2) // S-expression of three values<br>([hello][there]) // S-expression containing two lists<br><br>(a+-b) ( 'a' '+-' 'b' ) // Equivalent; three symbols<br>(a.b;) ( 'a' '.' 'b' ';') // Equivalent; four symbols<br></span>
+</code></pre><p>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.</p><hr><h2 id="Next.up">Next up<a class="permalink" href="ion/:%20Tutorial/:4.%20Special%20Datatypes#Next.up">#</a>
+</h2><ul>
+<li>
+<a href="ion/:%20Tutorial/:5.%20Symbols,%20Tables%20and%20Catalogs">Symbols, Tables and Catalogs</a>
+</li>
+</ul>
+ <div class="comments">
+ <style>.giscus-frame {min-height: 16em;}</style>
+ <script>
+ function giscus_load(button) {
+ let script = document.createElement("script");
+ script.setAttribute("data-repo", 'awesomized/ext-ion');
+ script.setAttribute("data-category", 'Comments on Docs');
+ script.setAttribute("data-repo-id", 'R_kgDOGfXEXw');
+ script.setAttribute("data-category-id", 'DIC_kwDOGfXEX84CBHuf');
+ script.setAttribute("data-mapping", 'og:title');
+ script.setAttribute("data-input-position", 'bottom');
+ script.setAttribute("data-reactions-enabled", false);
+ script.setAttribute("data-theme", 'light');
+ script.setAttribute("data-lang", 'en');
+
+ script.src = "//giscus.app/client.js";
+ button.parentNode.replaceChild(script, button);
+ }
+ </script>
+ <button class="activator" onclick="giscus_load(this)">Show Comments from Github Discussions</button>
+
+ </div>
+
+ <footer>
+
+<ul>
+ <li><a href="https://github.com/m6w6/mdref">mdref-v3.0
+</a></li>
+ <li><a href="LICENSE">© 2013-2022 All rights reserved.</a></li>
+ <li>
+</li>
+</ul>
+
+ </footer>
+
+ <script src="index.js" defer></script>
+
+ </div>
+ </body>
+</html>
--- /dev/null
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ ★4. Symbols, Tables and Catalogs -
+ mdref
+ </title>
+ <meta property="og:title" content="ion/: Tutorial/:4. Symbols, Tables and Catalogs">
+ <meta name="viewport" content="width=1200, initial-scale=0.5">
+ <base href="/ext-ion/v0.1/">
+ <meta http-equiv="Content-Location" content="/ext-ion/v0.1/ion/: Tutorial/:4. Symbols, Tables and Catalogs">
+ <link rel="stylesheet" href="index.css">
+
+ <link rel="shortcut icon" href="/ext-ion/v0.1/favicon.ico">
+ </head>
+ <body>
+ <div class="page">
+
+<div class="sidebar">
+
+ <div class="edit">
+ <a href="https://github.com/awesomized/ext-ion/edit/master/ion.stub.php">Edit</a>
+ </div>
+
+
+ <ul>
+ <li>↰ <a href="./">Home</a>
+
+ <ul>
+ <li>
+
+ ↑ <a href="./ion">
+ ion
+ </a>
+ <ul>
+ <li>
+
+ ↑ <a href="./ion/: Tutorial">
+ ★ Tutorial
+ </a>
+ <ul>
+ <li>
+
+ ↻ <strong><a href="./ion/: Tutorial/:4. Symbols, Tables and Catalogs">★4. Symbols, Tables and Catalogs</a></strong>
+
+
+
+ </ul>
+
+ <li>↲ <a href="./ion/: Tutorial/:1. Getting started">★1. Getting started</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:2. What is ion">★2. What is ion</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:3. Standard Datatypes">★3. Standard Datatypes</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:4. Special Datatypes">★4. Special Datatypes</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:5. Symbols, Tables and Catalogs">★5. Symbols, Tables and Catalogs</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/Untitled">Untitled</a></li>
+
+ </ul>
+
+ </li>
+ </ul>
+
+ </li>
+ </ul>
+</div>
+ <meta charset="utf-8"><h1>
+<a class="permalink" href="ion/:%20Tutorial/:4.%20Symbols,%20Tables%20and%20Catalogs#">#</a>Symbols, Tables and Catalogs</h1><h2 id="Catalog">Catalog<a class="permalink" href="ion/:%20Tutorial/:4.%20Symbols,%20Tables%20and%20Catalogs#Catalog">#</a>
+</h2><p>The Catalog holds a collection of <a href="ion/Symbol/Table">ion\Symbol\Table</a> instances queried from <a href="ion/Reader">ion\Reader</a> and <a href="ion/Writer">ion\Writer</a> instances.</p><p>See also <a href="https://amzn.github.io/ion-docs/docs/symbols.html#the-catalog">the ION spec's symbol guide chapter on catalog</a>.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br>$catalog </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Catalog</span><span style="color: inherit" class="keyword">;<br></span><span style="color: inherit" class="default">$symtab </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">ion\Symbol\PHP</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">asTable</span><span style="color: inherit" class="keyword">();<br></span><span style="color: inherit" class="default">$catalog</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">add</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$symtab</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre>
+ <div class="comments">
+ <style>.giscus-frame {min-height: 16em;}</style>
+ <script>
+ function giscus_load(button) {
+ let script = document.createElement("script");
+ script.setAttribute("data-repo", 'awesomized/ext-ion');
+ script.setAttribute("data-category", 'Comments on Docs');
+ script.setAttribute("data-repo-id", 'R_kgDOGfXEXw');
+ script.setAttribute("data-category-id", 'DIC_kwDOGfXEX84CBHuf');
+ script.setAttribute("data-mapping", 'og:title');
+ script.setAttribute("data-input-position", 'bottom');
+ script.setAttribute("data-reactions-enabled", false);
+ script.setAttribute("data-theme", 'light');
+ script.setAttribute("data-lang", 'en');
+
+ script.src = "//giscus.app/client.js";
+ button.parentNode.replaceChild(script, button);
+ }
+ </script>
+ <button class="activator" onclick="giscus_load(this)">Show Comments from Github Discussions</button>
+
+ </div>
+
+ <footer>
+
+<ul>
+ <li><a href="https://github.com/m6w6/mdref">mdref-v3.0
+</a></li>
+ <li><a href="LICENSE">© 2013-2022 All rights reserved.</a></li>
+ <li>
+</li>
+</ul>
+
+ </footer>
+
+ <script src="index.js" defer></script>
+
+ </div>
+ </body>
+</html>
--- /dev/null
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ ★5. Symbols, Tables and Catalogs -
+ mdref
+ </title>
+ <meta property="og:title" content="ion/: Tutorial/:5. Symbols, Tables and Catalogs">
+ <meta name="viewport" content="width=1200, initial-scale=0.5">
+ <base href="/ext-ion/v0.1/">
+ <meta http-equiv="Content-Location" content="/ext-ion/v0.1/ion/: Tutorial/:5. Symbols, Tables and Catalogs">
+ <link rel="stylesheet" href="index.css">
+
+ <link rel="shortcut icon" href="/ext-ion/v0.1/favicon.ico">
+ </head>
+ <body>
+ <div class="page">
+
+<div class="sidebar">
+
+ <div class="edit">
+ <a href="https://github.com/awesomized/ext-ion/edit/master/ion.stub.php">Edit</a>
+ </div>
+
+
+ <ul>
+ <li>↰ <a href="./">Home</a>
+
+ <ul>
+ <li>
+
+ ↑ <a href="./ion">
+ ion
+ </a>
+ <ul>
+ <li>
+
+ ↑ <a href="./ion/: Tutorial">
+ ★ Tutorial
+ </a>
+ <ul>
+ <li>
+
+ ↻ <strong><a href="./ion/: Tutorial/:5. Symbols, Tables and Catalogs">★5. Symbols, Tables and Catalogs</a></strong>
+
+
+
+ </ul>
+
+ <li>↲ <a href="./ion/: Tutorial/:1. Getting started">★1. Getting started</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:2. What is ion">★2. What is ion</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:3. Standard Datatypes">★3. Standard Datatypes</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:4. Special Datatypes">★4. Special Datatypes</a></li>
+
+ </ul>
+
+ </li>
+ </ul>
+
+ </li>
+ </ul>
+</div>
+ <meta charset="utf-8"><h1>
+<a class="permalink" href="ion/:%20Tutorial/:5.%20Symbols,%20Tables%20and%20Catalogs#">#</a>Symbols, Tables and Catalogs</h1><h2 id="Schematic.Overview">Schematic Overview<a class="permalink" href="ion/:%20Tutorial/:5.%20Symbols,%20Tables%20and%20Catalogs#Schematic.Overview">#</a>
+</h2><pre><code><span style="color: inherit" class="html">
+ +---------+<br> | Catalog |<br> +----+----+-------------------------------+<br> | | |<br> | | +-------------+ |<br> | +--->| SymbolTable | |<br> | | +---+---------+---------------+ |<br> | | | | | |<br> | | | | +-------------------+ |<br> | | | | | Symbol (ID, Text) | |<br> | | | +---->| Symbol (ID, Text) | |<br> | | | | ... | |<br> | | +---------+-------------------+ |<br> | | |<br> | | +-------------+ |<br> | +--->| SymbolTable | |<br> | | +---+---------+---------------+ |<br> | | | | | |<br> | . | | +-------------------+ |<br> | . | +---->| Symbol (ID, Text) | |<br> | . | | ... | |<br> | . +---------+-------------------+ |<br> | . |<br> +-----------------------------------------+<br></span>
+</code></pre><h2 id="Catalog">Catalog<a class="permalink" href="ion/:%20Tutorial/:5.%20Symbols,%20Tables%20and%20Catalogs#Catalog">#</a>
+</h2><p>The Catalog holds a collection of <a href="ion/Symbol/Table">ion\Symbol\Table</a> instances queried from <a href="ion/Reader">ion\Reader</a> and <a href="ion/Writer">ion\Writer</a> instances.</p><p>See also <a href="https://amzn.github.io/ion-docs/docs/symbols.html#the-catalog">the ION spec's symbol guide chapter on catalogs</a>.</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br>$catalog </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Catalog</span><span style="color: inherit" class="keyword">;<br></span><span style="color: inherit" class="default">$symtab </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">ion\Symbol\PHP</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">asTable</span><span style="color: inherit" class="keyword">();<br></span><span style="color: inherit" class="default">$catalog</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">add</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$symtab</span><span style="color: inherit" class="keyword">);<br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><h2 id="Symbol.Table">Symbol Table<a class="permalink" href="ion/:%20Tutorial/:5.%20Symbols,%20Tables%20and%20Catalogs#Symbol.Table">#</a>
+</h2><p>There are three types of symbol tables:</p><ul>
+<li>Local</li>
+<li>Shared</li>
+<li>System (a special shared symbol table)</li>
+</ul><p>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.</p><p>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.</p><h3 id="Using.a.shared.symbol.table">Using a shared symbol table<a class="permalink" href="ion/:%20Tutorial/:5.%20Symbols,%20Tables%20and%20Catalogs#Using.a.shared.symbol.table">#</a>
+</h3><p>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.</p><p>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.</p><p>Consider the following CSV in a file called <code>test.csv</code>.</p><pre><code><span style="color: inherit" class="html">
+ id,type,state<br> 1,foo,false<br> 2,bar,true<br> 3,baz,true<br> ...<br></span>
+</code></pre><p>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.</p><p>Consider the following shared symbol table that declares the column names of <code>test.csv</code> as symbols. Note that the shared symbol table may have been generated by hand or programmatically.</p><pre><code><span style="color: inherit" class="html">
+ $ion_shared_symbol_table::{<br> name: "test.csv.columns",<br> version: 1,<br> symbols: ["id", "type", "state"],<br> }<br></span>
+</code></pre><p>This shared symbol table can be stored in a file (or in a database, etc.) to be resurrected into a symbol table at runtime.</p><p>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.</p><p>Consider the following complete example:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br><br></span><span style="color: inherit" class="comment">/**<br> * Representing a CSV row<br> */<br></span><span style="color: inherit" class="keyword">class </span><span style="color: inherit" class="default">Row </span><span style="color: inherit" class="keyword">{<br> public function </span><span style="color: inherit" class="default">__construct</span><span style="color: inherit" class="keyword">(<br> public readonly </span><span style="color: inherit" class="default">int $id</span><span style="color: inherit" class="keyword">,<br> public readonly </span><span style="color: inherit" class="default">string $type</span><span style="color: inherit" class="keyword">,<br> public readonly </span><span style="color: inherit" class="default">bool $state </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">true<br> </span><span style="color: inherit" class="keyword">) {}<br>}<br><br></span><span style="color: inherit" class="comment">/* Fetch the shared symbol table from file, db, etc. */<br></span><span style="color: inherit" class="default">$symtab </span><span style="color: inherit" class="keyword">= </span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(<<<'SymbolTable'<br></span><span style="color: inherit" class="string"> $ion_shared_symbol_table::{<br> name: "test.csv.columns",<br> version: 1,<br> symbols: ["id", "type", "state"],<br> }<br></span><span style="color: inherit" class="keyword">SymbolTable<br>);<br><br></span><span style="color: inherit" class="comment">/* Add the shared symbol table to a catalog */<br></span><span style="color: inherit" class="default">$catalog </span><span style="color: inherit" class="keyword">= new </span><span style="color: inherit" class="default">ion\Catalog</span><span style="color: inherit" class="keyword">;<br></span><span style="color: inherit" class="default">$catalog</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">add</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$symtab</span><span style="color: inherit" class="keyword">);<br><br></span><span style="color: inherit" class="comment">/* Use the catalog when writing the data */<br></span><span style="color: inherit" class="default">$writer </span><span style="color: inherit" class="keyword">= new class(</span><span style="color: inherit" class="default">options</span><span style="color: inherit" class="keyword">: new </span><span style="color: inherit" class="default">ion\Writer\Options</span><span style="color: inherit" class="keyword">(<br> </span><span style="color: inherit" class="default">catalog</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="default">$catalog</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="default">outputBinary</span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="default">true<br></span><span style="color: inherit" class="keyword">)) extends </span><span style="color: inherit" class="default">ion\Writer\Buffer\Writer </span><span style="color: inherit" class="keyword">{<br> public function </span><span style="color: inherit" class="default">writeRow</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">Row $row</span><span style="color: inherit" class="keyword">) : </span><span style="color: inherit" class="default">void </span><span style="color: inherit" class="keyword">{<br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">startContainer</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\Type</span><span style="color: inherit" class="keyword">::</span><span style="color: inherit" class="default">Struct</span><span style="color: inherit" class="keyword">);<br> <br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeFieldname</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"id"</span><span style="color: inherit" class="keyword">);<br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeInt</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$row</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">id</span><span style="color: inherit" class="keyword">);<br> <br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeFieldName</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"type"</span><span style="color: inherit" class="keyword">);<br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeString</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$row</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">type</span><span style="color: inherit" class="keyword">);<br> <br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeFieldName</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"state"</span><span style="color: inherit" class="keyword">);<br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeBool</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$row</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">state</span><span style="color: inherit" class="keyword">);<br> <br> </span><span style="color: inherit" class="default">$this</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">finishContainer</span><span style="color: inherit" class="keyword">();<br> }<br>};<br><br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeRow</span><span style="color: inherit" class="keyword">(new </span><span style="color: inherit" class="default">Row</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">1</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="string">"foo"</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="default">false</span><span style="color: inherit" class="keyword">));<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeRow</span><span style="color: inherit" class="keyword">(new </span><span style="color: inherit" class="default">Row</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">2</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="string">"bar"</span><span style="color: inherit" class="keyword">));<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">writeRow</span><span style="color: inherit" class="keyword">(new </span><span style="color: inherit" class="default">Row</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">3</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="string">"baz"</span><span style="color: inherit" class="keyword">));<br></span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">flush</span><span style="color: inherit" class="keyword">();<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>Let's inspect the binary ION stream and verify that the column names are actually replaced by SymbolIDs:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br></span><span style="color: inherit" class="keyword">foreach (</span><span style="color: inherit" class="default">str_split</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">getBuffer</span><span style="color: inherit" class="keyword">(), </span><span style="color: inherit" class="default">8</span><span style="color: inherit" class="keyword">) as </span><span style="color: inherit" class="default">$line</span><span style="color: inherit" class="keyword">) {<br> </span><span style="color: inherit" class="default">printf</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="string">"%-26s"</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="default">chunk_split</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">bin2hex</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$line</span><span style="color: inherit" class="keyword">), </span><span style="color: inherit" class="default">2</span><span style="color: inherit" class="keyword">, </span><span style="color: inherit" class="string">" "</span><span style="color: inherit" class="keyword">));<br> foreach (</span><span style="color: inherit" class="default">str_split</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$line</span><span style="color: inherit" class="keyword">) as </span><span style="color: inherit" class="default">$byte</span><span style="color: inherit" class="keyword">) {<br> echo </span><span style="color: inherit" class="default">$byte </span><span style="color: inherit" class="keyword">>= </span><span style="color: inherit" class="string">' ' </span><span style="color: inherit" class="keyword">&& </span><span style="color: inherit" class="default">$byte </span><span style="color: inherit" class="keyword"><= </span><span style="color: inherit" class="string">'~' </span><span style="color: inherit" class="keyword">? </span><span style="color: inherit" class="default">$byte </span><span style="color: inherit" class="keyword">: </span><span style="color: inherit" class="string">"."</span><span style="color: inherit" class="keyword">;<br> }<br> echo </span><span style="color: inherit" class="string">"\n"</span><span style="color: inherit" class="keyword">;<br>}<br>echo </span><span style="color: inherit" class="string">"\n"</span><span style="color: inherit" class="keyword">;<br><br></span><span style="color: inherit" class="comment">/*<br> e0 01 00 ea ee a2 81 83 ........ \ <br> de 9e 86 be 9b de 99 84 ........ |<br> 8e 90 74 65 73 74 2e 63 ..test.c > here's ION symbol table metadata<br> 73 76 2e 63 6f 6c 75 6d sv.colum |<br> 6e 73 85 21 01 88 21 03 ns.!..!. <<br> da 8a 21 01 8b 83 66 6f ..!...fo |<br> 6f 8c 11 da 8a 21 02 8b o....!.. > here's the actual data<br> 83 62 61 72 8c 11 da 8a .bar.... |<br> 21 03 8b 83 62 61 7a 8c !...baz. /<br> 11 .<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>When unserializing without knowing the used symbols, our column name will actually be just symbol IDs <code>$<SID></code>:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br><br>var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">getBuffer</span><span style="color: inherit" class="keyword">(), [<br> </span><span style="color: inherit" class="string">"multiSequence" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="default">true</span><span style="color: inherit" class="keyword">,<br>]));<br><br></span><span style="color: inherit" class="comment">/*<br>array(3) {<br> [0]=><br> array(3) {<br> ["$10"]=><br> int(1)<br> ["$11"]=><br> string(3) "foo"<br> ["$12"]=><br> bool(false)<br> }<br> [1]=><br> array(3) {<br> ["$10"]=><br> int(2)<br> ["$11"]=><br> string(3) "bar"<br> ["$12"]=><br> bool(true)<br> }<br> [2]=><br> array(3) {<br> ["$10"]=><br> int(3)<br> ["$11"]=><br> string(3) "baz"<br> ["$12"]=><br> bool(true)<br> }<br>}<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre><p>When unserializing with known symbols, the symbol IDs will be resolved when using the catatalog with the appropriate symbol tables:</p><pre><code><span style="color: inherit" class="html">
+<span style="color: inherit" class="default"><?php<br> <br>var_dump</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">ion\unserialize</span><span style="color: inherit" class="keyword">(</span><span style="color: inherit" class="default">$writer</span><span style="color: inherit" class="keyword">-></span><span style="color: inherit" class="default">getBuffer</span><span style="color: inherit" class="keyword">(), [<br> </span><span style="color: inherit" class="string">"multiSequence" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="default">true</span><span style="color: inherit" class="keyword">,<br> </span><span style="color: inherit" class="string">"readerOptions" </span><span style="color: inherit" class="keyword">=> [<br> </span><span style="color: inherit" class="string">"catalog" </span><span style="color: inherit" class="keyword">=> </span><span style="color: inherit" class="default">$catalog<br> </span><span style="color: inherit" class="keyword">]<br>]));<br><br></span><span style="color: inherit" class="comment">/*<br> array(3) {<br> [0]=><br> array(3) {<br> ["id"]=><br> int(1)<br> ["type"]=><br> string(3) "foo"<br> ["state"]=><br> bool(false)<br> }<br> [1]=><br> array(3) {<br> ["id"]=><br> int(2)<br> ["type"]=><br> string(3) "bar"<br> ["state"]=><br> bool(true)<br> }<br> [2]=><br> array(3) {<br> ["id"]=><br> int(3)<br> ["type"]=><br> string(3) "baz"<br> ["state"]=><br> bool(true)<br> }<br> }<br>*/<br><br></span><span style="color: inherit" class="default">?><br></span>
+</span>
+</code></pre>
+ <div class="comments">
+ <style>.giscus-frame {min-height: 16em;}</style>
+ <script>
+ function giscus_load(button) {
+ let script = document.createElement("script");
+ script.setAttribute("data-repo", 'awesomized/ext-ion');
+ script.setAttribute("data-category", 'Comments on Docs');
+ script.setAttribute("data-repo-id", 'R_kgDOGfXEXw');
+ script.setAttribute("data-category-id", 'DIC_kwDOGfXEX84CBHuf');
+ script.setAttribute("data-mapping", 'og:title');
+ script.setAttribute("data-input-position", 'bottom');
+ script.setAttribute("data-reactions-enabled", false);
+ script.setAttribute("data-theme", 'light');
+ script.setAttribute("data-lang", 'en');
+
+ script.src = "//giscus.app/client.js";
+ button.parentNode.replaceChild(script, button);
+ }
+ </script>
+ <button class="activator" onclick="giscus_load(this)">Show Comments from Github Discussions</button>
+
+ </div>
+
+ <footer>
+
+<ul>
+ <li><a href="https://github.com/m6w6/mdref">mdref-v3.0
+</a></li>
+ <li><a href="LICENSE">© 2013-2022 All rights reserved.</a></li>
+ <li>
+</li>
+</ul>
+
+ </footer>
+
+ <script src="index.js" defer></script>
+
+ </div>
+ </body>
+</html>
--- /dev/null
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ Untitled -
+ mdref
+ </title>
+ <meta property="og:title" content="ion\: Tutorial\Untitled">
+ <meta name="viewport" content="width=1200, initial-scale=0.5">
+ <base href="/ext-ion/v0.1/">
+ <meta http-equiv="Content-Location" content="/ext-ion/v0.1/ion/: Tutorial/Untitled">
+ <link rel="stylesheet" href="index.css">
+
+ <link rel="shortcut icon" href="/ext-ion/v0.1/favicon.ico">
+ </head>
+ <body>
+ <div class="page">
+
+<div class="sidebar">
+
+ <div class="edit">
+ <a href="https://github.com/awesomized/ext-ion/edit/master/ion.stub.php">Edit</a>
+ </div>
+
+
+ <ul>
+ <li>↰ <a href="./">Home</a>
+
+ <ul>
+ <li>
+
+ ↑ <a href="./ion">
+ ion
+ </a>
+ <ul>
+ <li>
+
+ ↑ <a href="./ion/: Tutorial">
+ ★ Tutorial
+ </a>
+ <ul>
+ <li>
+
+ ↻ <strong><a href="./ion/: Tutorial/Untitled">Untitled</a></strong>
+
+
+
+ </ul>
+
+ <li>↲ <a href="./ion/: Tutorial/:1. Getting started">★1. Getting started</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:2. What is ion">★2. What is ion</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:3. Standard Datatypes">★3. Standard Datatypes</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:4. Special Datatypes">★4. Special Datatypes</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:4. Symbols, Tables and Catalogs">★4. Symbols, Tables and Catalogs</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial/:5. Symbols, Tables and Catalogs">★5. Symbols, Tables and Catalogs</a></li>
+
+ </ul>
+
+ </li>
+ </ul>
+
+ </li>
+ </ul>
+</div>
+ <meta charset="utf-8">
+ <div class="comments">
+ <style>.giscus-frame {min-height: 16em;}</style>
+ <script>
+ function giscus_load(button) {
+ let script = document.createElement("script");
+ script.setAttribute("data-repo", 'awesomized/ext-ion');
+ script.setAttribute("data-category", 'Comments on Docs');
+ script.setAttribute("data-repo-id", 'R_kgDOGfXEXw');
+ script.setAttribute("data-category-id", 'DIC_kwDOGfXEX84CBHuf');
+ script.setAttribute("data-mapping", 'og:title');
+ script.setAttribute("data-input-position", 'bottom');
+ script.setAttribute("data-reactions-enabled", false);
+ script.setAttribute("data-theme", 'light');
+ script.setAttribute("data-lang", 'en');
+
+ script.src = "//giscus.app/client.js";
+ button.parentNode.replaceChild(script, button);
+ }
+ </script>
+ <button class="activator" onclick="giscus_load(this)">Show Comments from Github Discussions</button>
+
+ </div>
+
+ <footer>
+
+<ul>
+ <li><a href="https://github.com/m6w6/mdref">mdref-v3.0
+</a></li>
+ <li><a href="LICENSE">© 2013-2022 All rights reserved.</a></li>
+ <li>
+</li>
+</ul>
+
+ </footer>
+
+ <script src="index.js" defer></script>
+
+ </div>
+ </body>
+</html>
<li>↲ <a href="./ion/: Contributing">★ Contributing</a></li>
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Exception">Exception</a></li>
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
</h2><p>None.</p><h2 id="Properties:">Properties:<a class="permalink" href="ion/Serializer/PHP#Properties:">#</a>
</h2><ul>
<li>
-<em>public</em> ?<a href="ion/Writer/Options">ion\Writer\Options</a> <span class="var" id="$writerOptions">$writerOptions<a class="permalink" href="ion/Serializer/PHP#%24writerOptions">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
+<em>public</em> <a href="ion/Writer/Options">ion\Writer\Options</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var" id="$writerOptions">$writerOptions<a class="permalink" href="ion/Serializer/PHP#%24writerOptions">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
Writer options.</li>
<li>
<em>public</em> <code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var" id="$multiSequence">$multiSequence<a class="permalink" href="ion/Serializer/PHP#%24multiSequence">#</a></span> = <code><a href="https://php.net/manual/en/language.types.boolean">false</a></code><br>
</h3>
<p>Create a new PHP ION serializer.</p>
- <p><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.void">void</a></code> <a href="ion/Serializer/PHP/__construct">ion\Serializer\PHP::__construct</a>([?<a href="ion/Writer/Options">ion\Writer\Options</a> <span class="var">$writerOptions</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$multiSequence</span> = <code><a href="https://php.net/manual/en/language.types.boolean">false</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$callMagicSerialize</span> = <code><a href="https://php.net/manual/en/language.types.boolean">true</a></code>, [?<code><a href="https://php.net/manual/en/language.types.string">string</a></code> <span class="var">$callCustomSerialize</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>]]]])</p>
+ <p><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.void">void</a></code> <a href="ion/Serializer/PHP/__construct">ion\Serializer\PHP::__construct</a>([<a href="ion/Writer/Options">ion\Writer\Options</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$writerOptions</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$multiSequence</span> = <code><a href="https://php.net/manual/en/language.types.boolean">false</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$callMagicSerialize</span> = <code><a href="https://php.net/manual/en/language.types.boolean">true</a></code>, [?<code><a href="https://php.net/manual/en/language.types.string">string</a></code> <span class="var">$callCustomSerialize</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>]]]])</p>
</li>
</ul>
</ul>
</div>
<meta charset="utf-8"><h1>
-<a class="permalink" href="ion/Serializer/PHP/__construct#">#</a><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.void">void</a></code> <a href="ion/Serializer/PHP/__construct">ion\Serializer\PHP::__construct</a>([?<a href="ion/Writer/Options">ion\Writer\Options</a> <span class="var">$writerOptions</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$multiSequence</span> = <code><a href="https://php.net/manual/en/language.types.boolean">false</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$callMagicSerialize</span> = <code><a href="https://php.net/manual/en/language.types.boolean">true</a></code>, [?<code><a href="https://php.net/manual/en/language.types.string">string</a></code> <span class="var">$callCustomSerialize</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>]]]])</h1><p>Create a new PHP ION serializer.</p><h2 id="Params:">Params:<a class="permalink" href="ion/Serializer/PHP/__construct#Params:">#</a>
+<a class="permalink" href="ion/Serializer/PHP/__construct#">#</a><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.void">void</a></code> <a href="ion/Serializer/PHP/__construct">ion\Serializer\PHP::__construct</a>([<a href="ion/Writer/Options">ion\Writer\Options</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$writerOptions</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$multiSequence</span> = <code><a href="https://php.net/manual/en/language.types.boolean">false</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$callMagicSerialize</span> = <code><a href="https://php.net/manual/en/language.types.boolean">true</a></code>, [?<code><a href="https://php.net/manual/en/language.types.string">string</a></code> <span class="var">$callCustomSerialize</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>]]]])</h1><p>Create a new PHP ION serializer.</p><h2 id="Params:">Params:<a class="permalink" href="ion/Serializer/PHP/__construct#Params:">#</a>
</h2><ul>
-<li>Optional ?<a href="ion/Writer/Options">ion\Writer\Options</a> <span class="var" id="$writerOptions">$writerOptions<a class="permalink" href="ion/Serializer/PHP/__construct#%24writerOptions">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
+<li>Optional <a href="ion/Writer/Options">ion\Writer\Options</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var" id="$writerOptions">$writerOptions<a class="permalink" href="ion/Serializer/PHP/__construct#%24writerOptions">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
Writer options.</li>
<li>Optional <code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var" id="$multiSequence">$multiSequence<a class="permalink" href="ion/Serializer/PHP/__construct#%24multiSequence">#</a></span> = <code><a href="https://php.net/manual/en/language.types.boolean">false</a></code><br>
Whether to write the top level <code><a href="https://php.net/manual/en/language.types.array">array</a></code> as multiple ION sequences.</li>
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
</h3>
<p>Create a new ION timestamp.</p>
- <p><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.void">void</a></code> <a href="ion/Timestamp/__construct">ion\Timestamp::__construct</a>(<a href="ion/Timestamp/Precision">ion\Timestamp\Precision</a>|<code><a href="https://php.net/manual/en/language.types.integer">int</a></code> <span class="var">$precision</span>, [<a href="ion/Timestamp/Format">ion\Timestamp\Format</a>|<code><a href="https://php.net/manual/en/language.types.string">string</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$format</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [?<code><a href="https://php.net/manual/en/language.types.string">string</a></code> <span class="var">$datetime</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [?<code><a href="https://php.net/manual/en/class.datetimezone">DateTimeZone</a></code> <span class="var">$timezone</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>]]])</p>
+ <p><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.void">void</a></code> <a href="ion/Timestamp/__construct">ion\Timestamp::__construct</a>(<a href="ion/Timestamp/Precision">ion\Timestamp\Precision</a>|<code><a href="https://php.net/manual/en/language.types.integer">int</a></code> <span class="var">$precision</span>, [<a href="ion/Timestamp/Format">ion\Timestamp\Format</a>|<code><a href="https://php.net/manual/en/language.types.string">string</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$format</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [?<code><a href="https://php.net/manual/en/language.types.string">string</a></code> <span class="var">$datetime</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [<code><a href="https://php.net/manual/en/class.datetimezone">DateTimeZone</a></code>|<code><a href="https://php.net/manual/en/language.types.string">string</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$timezone</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>]]])</p>
</li>
</ul><h2 id="Namespaces.Interfaces.and.Classes:">Namespaces, Interfaces and Classes:<a class="permalink" href="ion/Timestamp#Namespaces.Interfaces.and.Classes:">#</a>
</ul>
</div>
<meta charset="utf-8"><h1>
-<a class="permalink" href="ion/Timestamp/__construct#">#</a><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.void">void</a></code> <a href="ion/Timestamp/__construct">ion\Timestamp::__construct</a>(<a href="ion/Timestamp/Precision">ion\Timestamp\Precision</a>|<code><a href="https://php.net/manual/en/language.types.integer">int</a></code> <span class="var">$precision</span>, [<a href="ion/Timestamp/Format">ion\Timestamp\Format</a>|<code><a href="https://php.net/manual/en/language.types.string">string</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$format</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [?<code><a href="https://php.net/manual/en/language.types.string">string</a></code> <span class="var">$datetime</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [?<code><a href="https://php.net/manual/en/class.datetimezone">DateTimeZone</a></code> <span class="var">$timezone</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>]]])</h1><p>Create a new ION timestamp.</p><h2 id="Params:">Params:<a class="permalink" href="ion/Timestamp/__construct#Params:">#</a>
+<a class="permalink" href="ion/Timestamp/__construct#">#</a><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.void">void</a></code> <a href="ion/Timestamp/__construct">ion\Timestamp::__construct</a>(<a href="ion/Timestamp/Precision">ion\Timestamp\Precision</a>|<code><a href="https://php.net/manual/en/language.types.integer">int</a></code> <span class="var">$precision</span>, [<a href="ion/Timestamp/Format">ion\Timestamp\Format</a>|<code><a href="https://php.net/manual/en/language.types.string">string</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$format</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [?<code><a href="https://php.net/manual/en/language.types.string">string</a></code> <span class="var">$datetime</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [<code><a href="https://php.net/manual/en/class.datetimezone">DateTimeZone</a></code>|<code><a href="https://php.net/manual/en/language.types.string">string</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$timezone</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>]]])</h1><p>Create a new ION timestamp.</p><h2 id="Params:">Params:<a class="permalink" href="ion/Timestamp/__construct#Params:">#</a>
</h2><ul>
<li>
<a href="ion/Timestamp/Precision">ion\Timestamp\Precision</a>|<code><a href="https://php.net/manual/en/language.types.integer">int</a></code> <span class="var" id="$precision">$precision<a class="permalink" href="ion/Timestamp/__construct#%24precision">#</a></span><br>
The timestamp's format. See <a href="ion/Timestamp/Format">ion\Timestamp\Format</a>.</li>
<li>Optional ?<code><a href="https://php.net/manual/en/language.types.string">string</a></code> <span class="var" id="$datetime">$datetime<a class="permalink" href="ion/Timestamp/__construct#%24datetime">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
The timestamp's value.</li>
-<li>Optional ?<code><a href="https://php.net/manual/en/class.datetimezone">DateTimeZone</a></code> <span class="var" id="$timezone">$timezone<a class="permalink" href="ion/Timestamp/__construct#%24timezone">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
+<li>Optional <code><a href="https://php.net/manual/en/class.datetimezone">DateTimeZone</a></code>|<code><a href="https://php.net/manual/en/language.types.string">string</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var" id="$timezone">$timezone<a class="permalink" href="ion/Timestamp/__construct#%24timezone">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
The timestamp's timezone.</li>
</ul>
<div class="comments">
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
<li><a href="ion/Decimal">ion\Decimal</a></li>
<li><a href="ion/Timestamp">ion\Timestamp</a></li>
<li><a href="ion/Symbol">ion\Symbol</a></li>
-<li><a href="ion#Lob">ion\Lob</a></li>
+<li><a href="ion/Lob">ion\Lob</a></li>
</ul><h2 id="Constants:">Constants:<a class="permalink" href="ion/Type#Constants:">#</a>
</h2><ul>
<li>
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
</h2><p>None.</p><h2 id="Properties:">Properties:<a class="permalink" href="ion/Unserializer/PHP#Properties:">#</a>
</h2><ul>
<li>
-<em>public</em> ?<a href="ion/Reader/Options">ion\Reader\Options</a> <span class="var" id="$readerOptions">$readerOptions<a class="permalink" href="ion/Unserializer/PHP#%24readerOptions">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
+<em>public</em> <a href="ion/Reader/Options">ion\Reader\Options</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var" id="$readerOptions">$readerOptions<a class="permalink" href="ion/Unserializer/PHP#%24readerOptions">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
Reader options.</li>
<li>
<em>public</em> <code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var" id="$multiSequence">$multiSequence<a class="permalink" href="ion/Unserializer/PHP#%24multiSequence">#</a></span> = <code><a href="https://php.net/manual/en/language.types.boolean">false</a></code><br>
</h3>
<p>Create a new ION PHP unserializer.</p>
- <p><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.void">void</a></code> <a href="ion/Unserializer/PHP/__construct">ion\Unserializer\PHP::__construct</a>([?<a href="ion/Reader/Options">ion\Reader\Options</a> <span class="var">$readerOptions</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$multiSequence</span> = <code><a href="https://php.net/manual/en/language.types.boolean">false</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$callMagicUnserialize</span> = <code><a href="https://php.net/manual/en/language.types.boolean">true</a></code>, [?<code><a href="https://php.net/manual/en/language.types.string">string</a></code> <span class="var">$callCustomUnserialize</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>]]]])</p>
+ <p><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.void">void</a></code> <a href="ion/Unserializer/PHP/__construct">ion\Unserializer\PHP::__construct</a>([<a href="ion/Reader/Options">ion\Reader\Options</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$readerOptions</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$multiSequence</span> = <code><a href="https://php.net/manual/en/language.types.boolean">false</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$callMagicUnserialize</span> = <code><a href="https://php.net/manual/en/language.types.boolean">true</a></code>, [?<code><a href="https://php.net/manual/en/language.types.string">string</a></code> <span class="var">$callCustomUnserialize</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>]]]])</p>
</li>
</ul>
</ul>
</div>
<meta charset="utf-8"><h1>
-<a class="permalink" href="ion/Unserializer/PHP/__construct#">#</a><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.void">void</a></code> <a href="ion/Unserializer/PHP/__construct">ion\Unserializer\PHP::__construct</a>([?<a href="ion/Reader/Options">ion\Reader\Options</a> <span class="var">$readerOptions</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$multiSequence</span> = <code><a href="https://php.net/manual/en/language.types.boolean">false</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$callMagicUnserialize</span> = <code><a href="https://php.net/manual/en/language.types.boolean">true</a></code>, [?<code><a href="https://php.net/manual/en/language.types.string">string</a></code> <span class="var">$callCustomUnserialize</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>]]]])</h1><p>Create a new ION PHP unserializer.</p><h2 id="Params:">Params:<a class="permalink" href="ion/Unserializer/PHP/__construct#Params:">#</a>
+<a class="permalink" href="ion/Unserializer/PHP/__construct#">#</a><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.void">void</a></code> <a href="ion/Unserializer/PHP/__construct">ion\Unserializer\PHP::__construct</a>([<a href="ion/Reader/Options">ion\Reader\Options</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$readerOptions</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$multiSequence</span> = <code><a href="https://php.net/manual/en/language.types.boolean">false</a></code>, [<code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var">$callMagicUnserialize</span> = <code><a href="https://php.net/manual/en/language.types.boolean">true</a></code>, [?<code><a href="https://php.net/manual/en/language.types.string">string</a></code> <span class="var">$callCustomUnserialize</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>]]]])</h1><p>Create a new ION PHP unserializer.</p><h2 id="Params:">Params:<a class="permalink" href="ion/Unserializer/PHP/__construct#Params:">#</a>
</h2><ul>
-<li>Optional ?<a href="ion/Reader/Options">ion\Reader\Options</a> <span class="var" id="$readerOptions">$readerOptions<a class="permalink" href="ion/Unserializer/PHP/__construct#%24readerOptions">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
+<li>Optional <a href="ion/Reader/Options">ion\Reader\Options</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var" id="$readerOptions">$readerOptions<a class="permalink" href="ion/Unserializer/PHP/__construct#%24readerOptions">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
Reader options.</li>
<li>Optional <code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code> <span class="var" id="$multiSequence">$multiSequence<a class="permalink" href="ion/Unserializer/PHP/__construct#%24multiSequence">#</a></span> = <code><a href="https://php.net/manual/en/language.types.boolean">false</a></code><br>
Whether to continue reading multiple ION sequences after the first one.</li>
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
</ul>
</div>
<meta charset="utf-8"><h1>
-<a class="permalink" href="ion/serialize#">#</a><code><a href="https://php.net/manual/en/language.types.string">string</a></code> <a href="ion/serialize">ion\serialize</a>(<code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.mixed">mixed</a></code> <span class="var">$data</span>, [?<a href="ion/Serializer">ion\Serializer</a> <span class="var">$serializer</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>])</h1><p>Serialize a PHP value as ION data.</p><p>Serializes supported PHP values with the optionally provided <a href="ion/Serializer">\ion\Serializer:</a></p><ul>
+<a class="permalink" href="ion/serialize#">#</a><code><a href="https://php.net/manual/en/language.types.string">string</a></code> <a href="ion/serialize">ion\serialize</a>(<code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.mixed">mixed</a></code> <span class="var">$data</span>, [<a href="ion/Serializer">ion\Serializer</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$serializer</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>])</h1><p>Serialize a PHP value as ION data.</p><p>Serializes supported PHP values with the optionally provided <a href="ion/Serializer">\ion\Serializer:</a></p><ul>
<li><code><a href="https://php.net/manual/en/language.types.null">NULL</a></code></li>
<li><code><a href="https://php.net/manual/en/language.types.boolean">bool</a></code></li>
<li><code><a href="https://php.net/manual/en/language.types.integer">int</a></code></li>
<li>
<code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.mixed">mixed</a></code> <span class="var" id="$data">$data<a class="permalink" href="ion/serialize#%24data">#</a></span><br>
PHP value(s).</li>
-<li>Optional ?<a href="ion/Serializer">ion\Serializer</a> <span class="var" id="$serializer">$serializer<a class="permalink" href="ion/serialize#%24serializer">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
+<li>Optional <a href="ion/Serializer">ion\Serializer</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var" id="$serializer">$serializer<a class="permalink" href="ion/serialize#%24serializer">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
Custom serializer.</li>
</ul><h2 id="Returns:">Returns:<a class="permalink" href="ion/serialize#Returns:">#</a>
</h2><ul>
<li>↲ <a href="./ion/: Security">★ Security</a></li>
+ <li>↲ <a href="./ion/: Tutorial">★ Tutorial</a></li>
+
<li>↲ <a href="./ion/Catalog">Catalog</a></li>
<li>↲ <a href="./ion/Decimal">Decimal</a></li>
</ul>
</div>
<meta charset="utf-8"><h1>
-<a class="permalink" href="ion/unserialize#">#</a><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.mixed">mixed</a></code> <a href="ion/unserialize">ion\unserialize</a>(<code><a href="https://php.net/manual/en/language.types.string">string</a></code>|<code><a href="https://php.net/manual/en/language.types.resource">resource</a></code> <span class="var">$data</span>, [?<a href="ion/Unserializer">ion\Unserializer</a> <span class="var">$unserializer</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>])</h1><p>Unserialize ION data (stream) as PHP value(s).</p><h2 id="Params:">Params:<a class="permalink" href="ion/unserialize#Params:">#</a>
+<a class="permalink" href="ion/unserialize#">#</a><code><a href="https://php.net/manual/en/language.types.declarations#language.types.declarations.mixed">mixed</a></code> <a href="ion/unserialize">ion\unserialize</a>(<code><a href="https://php.net/manual/en/language.types.string">string</a></code>|<code><a href="https://php.net/manual/en/language.types.resource">resource</a></code> <span class="var">$data</span>, [<a href="ion/Unserializer">ion\Unserializer</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var">$unserializer</span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code>])</h1><p>Unserialize ION data (stream) as PHP value(s).</p><h2 id="Params:">Params:<a class="permalink" href="ion/unserialize#Params:">#</a>
</h2><ul>
<li>
<code><a href="https://php.net/manual/en/language.types.string">string</a></code>|<code><a href="https://php.net/manual/en/language.types.resource">resource</a></code> <span class="var" id="$data">$data<a class="permalink" href="ion/unserialize#%24data">#</a></span><br>
Serialized ION data, either as <code><a href="https://php.net/manual/en/language.types.string">string</a></code> buffer or stream.</li>
-<li>Optional ?<a href="ion/Unserializer">ion\Unserializer</a> <span class="var" id="$unserializer">$unserializer<a class="permalink" href="ion/unserialize#%24unserializer">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
+<li>Optional <a href="ion/Unserializer">ion\Unserializer</a>|<code><a href="https://php.net/manual/en/language.types.array">array</a></code>|<code><a href="https://php.net/manual/en/language.types.null">null</a></code> <span class="var" id="$unserializer">$unserializer<a class="permalink" href="ion/unserialize#%24unserializer">#</a></span> = <code><a href="https://php.net/manual/en/language.types.null">NULL</a></code><br>
Unserialize ION data (stream) as PHP value(s).</li>
</ul><h2 id="Returns:">Returns:<a class="permalink" href="ion/unserialize#Returns:">#</a>
</h2><ul>