├── .phpunit-watcher.yml ├── .styleci.yml ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json ├── infection.json.dist ├── psalm.xml └── src ├── CallbackSerializer.php ├── IgbinarySerializer.php ├── JsonObjectSerializer.php ├── JsonSerializer.php ├── ObjectSerializerInterface.php ├── ObjectSerializerTrait.php ├── PhpSerializer.php ├── SerializerInterface.php ├── XmlObjectSerializer.php └── XmlSerializer.php /.phpunit-watcher.yml: -------------------------------------------------------------------------------- 1 | watch: 2 | directories: 3 | - src 4 | - tests 5 | fileMask: '*.php' 6 | notifications: 7 | passingTests: false 8 | failingTests: false 9 | phpunit: 10 | binaryPath: vendor/bin/phpunit 11 | timeout: 180 12 | -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: psr12 2 | risky: true 3 | 4 | version: 8 5 | 6 | finder: 7 | exclude: 8 | - docs 9 | - vendor 10 | - resources 11 | - views 12 | - public 13 | - templates 14 | not-name: 15 | - UnionCar.php 16 | - TimerUnionTypes.php 17 | - schema1.php 18 | 19 | enabled: 20 | - alpha_ordered_traits 21 | - array_indentation 22 | - array_push 23 | - combine_consecutive_issets 24 | - combine_consecutive_unsets 25 | - combine_nested_dirname 26 | - declare_strict_types 27 | - dir_constant 28 | - final_static_access 29 | - fully_qualified_strict_types 30 | - function_to_constant 31 | - hash_to_slash_comment 32 | - is_null 33 | - logical_operators 34 | - magic_constant_casing 35 | - magic_method_casing 36 | - method_separation 37 | - modernize_types_casting 38 | - native_function_casing 39 | - native_function_type_declaration_casing 40 | - no_alias_functions 41 | - no_empty_comment 42 | - no_empty_phpdoc 43 | - no_empty_statement 44 | - no_extra_block_blank_lines 45 | - no_short_bool_cast 46 | - no_superfluous_elseif 47 | - no_unneeded_control_parentheses 48 | - no_unneeded_curly_braces 49 | - no_unneeded_final_method 50 | - no_unset_cast 51 | - no_unused_imports 52 | - no_unused_lambda_imports 53 | - no_useless_else 54 | - no_useless_return 55 | - normalize_index_brace 56 | - php_unit_dedicate_assert 57 | - php_unit_dedicate_assert_internal_type 58 | - php_unit_expectation 59 | - php_unit_mock 60 | - php_unit_mock_short_will_return 61 | - php_unit_namespaced 62 | - php_unit_no_expectation_annotation 63 | - phpdoc_no_empty_return 64 | - phpdoc_no_useless_inheritdoc 65 | - phpdoc_order 66 | - phpdoc_property 67 | - phpdoc_scalar 68 | - phpdoc_separation 69 | - phpdoc_singular_inheritdoc 70 | - phpdoc_trim 71 | - phpdoc_trim_consecutive_blank_line_separation 72 | - phpdoc_type_to_var 73 | - phpdoc_types 74 | - phpdoc_types_order 75 | - print_to_echo 76 | - regular_callable_call 77 | - return_assignment 78 | - self_accessor 79 | - self_static_accessor 80 | - set_type_to_cast 81 | - short_array_syntax 82 | - short_list_syntax 83 | - simplified_if_return 84 | - single_quote 85 | - standardize_not_equals 86 | - ternary_to_null_coalescing 87 | - trailing_comma_in_multiline_array 88 | - unalign_double_arrow 89 | - unalign_equals 90 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # _____ Change Log 2 | 3 | ## 1.0.0 under development 4 | 5 | - Initial release. 6 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright © 2008 by Yii Software (https://www.yiiframework.com/) 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Yii Software nor the names of its 15 | contributors may be used to endorse or promote products derived 16 | from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 |

Yii Serializer Library

6 |
7 |

8 | 9 | The package ... 10 | 11 | [![Latest Stable Version](https://poser.pugx.org/yiisoft/serializer/v/stable.png)](https://packagist.org/packages/yiisoft/serializer) 12 | [![Total Downloads](https://poser.pugx.org/yiisoft/serializer/downloads.png)](https://packagist.org/packages/yiisoft/serializer) 13 | [![Build Status](https://github.com/yiisoft/serializer/workflows/build/badge.svg)](https://github.com/yiisoft/serializer/actions) 14 | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/yiisoft/serializer/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/yiisoft/serializer/?branch=master) 15 | [![Code Coverage](https://scrutinizer-ci.com/g/yiisoft/serializer/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/yiisoft/serializer/?branch=master) 16 | [![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fyiisoft%2Fserializer%2Fmaster)](https://dashboard.stryker-mutator.io/reports/github.com/yiisoft/serializer/master) 17 | [![static analysis](https://github.com/yiisoft/serializer/workflows/static%20analysis/badge.svg)](https://github.com/yiisoft/serializer/actions?query=workflow%3A%22static+analysis%22) 18 | [![type-coverage](https://shepherd.dev/github/yiisoft/serializer/coverage.svg)](https://shepherd.dev/github/yiisoft/serializer) 19 | 20 | ## General usage 21 | 22 | ### Unit testing 23 | 24 | The package is tested with [PHPUnit](https://phpunit.de/). To run tests: 25 | 26 | ```shell 27 | ./vendor/bin/phpunit 28 | ``` 29 | 30 | ### Mutation testing 31 | 32 | The package tests are checked with [Infection](https://infection.github.io/) mutation framework. To run it: 33 | 34 | ```shell 35 | ./vendor/bin/infection 36 | ``` 37 | 38 | ### Static analysis 39 | 40 | The code is statically analyzed with [Psalm](https://psalm.dev/). To run static analysis: 41 | 42 | ```shell 43 | ./vendor/bin/psalm 44 | ``` 45 | 46 | ### Support the project 47 | 48 | [![Open Collective](https://img.shields.io/badge/Open%20Collective-sponsor-7eadf1?logo=open%20collective&logoColor=7eadf1&labelColor=555555)](https://opencollective.com/yiisoft) 49 | 50 | ### Follow updates 51 | 52 | [![Official website](https://img.shields.io/badge/Powered_by-Yii_Framework-green.svg?style=flat)](https://www.yiiframework.com/) 53 | [![Twitter](https://img.shields.io/badge/twitter-follow-1DA1F2?logo=twitter&logoColor=1DA1F2&labelColor=555555?style=flat)](https://twitter.com/yiiframework) 54 | [![Telegram](https://img.shields.io/badge/telegram-join-1DA1F2?style=flat&logo=telegram)](https://t.me/yii3en) 55 | [![Facebook](https://img.shields.io/badge/facebook-join-1DA1F2?style=flat&logo=facebook&logoColor=ffffff)](https://www.facebook.com/groups/yiitalk) 56 | [![Slack](https://img.shields.io/badge/slack-join-1DA1F2?style=flat&logo=slack)](https://yiiframework.com/go/slack) 57 | 58 | ## License 59 | 60 | The Yii Serializer Library is free software. It is released under the terms of the BSD License. 61 | Please see [`LICENSE`](./LICENSE.md) for more information. 62 | 63 | Maintained by [Yii Software](https://www.yiiframework.com/). 64 | 65 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yiisoft/serializer", 3 | "type": "library", 4 | "description": "Yii Serializer Library", 5 | "keywords": [ 6 | "yii", 7 | "serializer" 8 | ], 9 | "homepage": "http://www.yiiframework.com/", 10 | "license": "BSD-3-Clause", 11 | "support": { 12 | "issues": "https://github.com/yiisoft/serializer/issues?state=open", 13 | "forum": "http://www.yiiframework.com/forum/", 14 | "wiki": "http://www.yiiframework.com/wiki/", 15 | "irc": "irc://irc.freenode.net/yii", 16 | "source": "https://github.com/yiisoft/serializer" 17 | }, 18 | "require": { 19 | "php": "^7.4|^8.0", 20 | "symfony/property-access": "^5.1.8", 21 | "symfony/serializer": "^5.1.8" 22 | }, 23 | "require-dev": { 24 | "phpunit/phpunit": "^9.4", 25 | "roave/infection-static-analysis-plugin": "^1.5", 26 | "spatie/phpunit-watcher": "^1.23", 27 | "vimeo/psalm": "^4.2" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "Yiisoft\\Serializer\\": "src" 32 | } 33 | }, 34 | "autoload-dev": { 35 | "psr-4": { 36 | "Yiisoft\\Serializer\\Tests\\": "tests" 37 | } 38 | }, 39 | "extra": { 40 | "branch-alias": { 41 | "dev-master": "3.0.x-dev" 42 | } 43 | }, 44 | "config": { 45 | "sort-packages": true 46 | }, 47 | "minimum-stability": "dev", 48 | "prefer-stable": true, 49 | "scripts": { 50 | "test": "phpunit --testdox --no-interaction", 51 | "test-watch": "phpunit-watcher watch" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /infection.json.dist: -------------------------------------------------------------------------------- 1 | { 2 | "source": { 3 | "directories": [ 4 | "src" 5 | ] 6 | }, 7 | "logs": { 8 | "text": "php:\/\/stderr", 9 | "badge": { 10 | "branch": "master" 11 | } 12 | }, 13 | "mutators": { 14 | "@default": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /psalm.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/CallbackSerializer.php: -------------------------------------------------------------------------------- 1 | serializeCallback = $serializeCallback; 29 | $this->unserializeCallback = $unserializeCallback; 30 | } 31 | 32 | public function serialize($value): string 33 | { 34 | return ($this->serializeCallback)($value); 35 | } 36 | 37 | public function unserialize(string $value) 38 | { 39 | return ($this->unserializeCallback)($value); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/IgbinarySerializer.php: -------------------------------------------------------------------------------- 1 | serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder( 31 | new JsonEncode([JsonEncode::OPTIONS => $options]), 32 | new JsonDecode([JsonDecode::ASSOCIATIVE => true]), 33 | )]); 34 | } 35 | 36 | public function serialize(object $object): string 37 | { 38 | return $this->serializer->serialize($object, JsonEncoder::FORMAT); 39 | } 40 | 41 | public function serializeMultiple(array $objects): string 42 | { 43 | $this->checkArrayObjects($objects); 44 | return $this->serializer->serialize($objects, JsonEncoder::FORMAT); 45 | } 46 | 47 | public function unserialize(string $value, string $class): object 48 | { 49 | $decodedValue = $this->checkAndDecodeData($value, $class, JsonEncoder::FORMAT); 50 | return $this->denormalizeObject($decodedValue, $class); 51 | } 52 | 53 | public function unserializeMultiple(string $value, string $class): array 54 | { 55 | $decodedValue = $this->checkAndDecodeData($value, $class, JsonEncoder::FORMAT); 56 | return $this->denormalizeObjects($decodedValue, $class); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/JsonSerializer.php: -------------------------------------------------------------------------------- 1 | serializer = new Serializer( 32 | [new JsonSerializableNormalizer(), new ObjectNormalizer()], 33 | [new JsonEncoder( 34 | new JsonEncode([JsonEncode::OPTIONS => $options]), 35 | new JsonDecode([JsonDecode::ASSOCIATIVE => true]), 36 | )], 37 | ); 38 | } 39 | 40 | public function serialize($value): string 41 | { 42 | return $this->serializer->serialize($value, JsonEncoder::FORMAT); 43 | } 44 | 45 | public function unserialize(string $value) 46 | { 47 | return $this->serializer->decode($value, JsonEncoder::FORMAT); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/ObjectSerializerInterface.php: -------------------------------------------------------------------------------- 1 | serializer->denormalize($data, $class); 36 | } catch (ExceptionInterface $e) { 37 | throw new InvalidArgumentException(sprintf( 38 | 'The data for restoring the object is incorrect. %s', 39 | $e->getMessage() 40 | )); 41 | } 42 | } 43 | 44 | /** 45 | * Restores array objects from the decoded data. 46 | * 47 | * @param mixed[] $data The decoded data for restoring the object. 48 | * @param string $class The class name of the objects to be restored. 49 | * 50 | * @throws InvalidArgumentException If the data to restore the objects is incorrect. 51 | * 52 | * @return object[] The restored array objects. 53 | * @psalm-suppress InvalidReturnType 54 | */ 55 | private function denormalizeObjects(array $data, string $class): array 56 | { 57 | foreach ($data as $key => $value) { 58 | $data[$key] = $this->denormalizeObject($value, $class); 59 | } 60 | 61 | return $data; 62 | } 63 | 64 | /** 65 | * Checks and decodes data from its serialized representations. 66 | * 67 | * @param string $data The serialized string. 68 | * @param string $class The name of the object class to be restored. 69 | * @param string $format The format of the sterilized data. 70 | * 71 | * @throws InvalidArgumentException if class does not exist or data to restore the object is incorrect. 72 | * 73 | * @return array The decoded data. 74 | */ 75 | private function checkAndDecodeData(string $data, string $class, string $format): array 76 | { 77 | if (!class_exists($class)) { 78 | throw new InvalidArgumentException(sprintf( 79 | 'The "%s" class does not exist.', 80 | $class 81 | )); 82 | } 83 | 84 | $decodedData = $this->serializer->decode($data, $format); 85 | 86 | if (!is_array($decodedData)) { 87 | throw new InvalidArgumentException('The data for restoring the object is incorrect.'); 88 | } 89 | 90 | return $decodedData; 91 | } 92 | 93 | /** 94 | * Checks that each item of the array is an object. 95 | * 96 | * @param array $objects 97 | * 98 | * @throws InvalidArgumentException if the array of objects is incorrect. 99 | */ 100 | private function checkArrayObjects(array $objects): void 101 | { 102 | foreach ($objects as $object) { 103 | if (!is_object($object)) { 104 | throw new InvalidArgumentException(sprintf( 105 | 'The array item must be an object, %s received.', 106 | gettype($object) 107 | )); 108 | } 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/PhpSerializer.php: -------------------------------------------------------------------------------- 1 | serializer = new Serializer([new ObjectNormalizer()], [new XmlEncoder([ 26 | XmlEncoder::ROOT_NODE_NAME => $rootTag, 27 | XmlEncoder::VERSION => $version, 28 | XmlEncoder::ENCODING => $encoding, 29 | ])]); 30 | } 31 | 32 | public function serialize(object $object): string 33 | { 34 | return $this->serializer->serialize($object, XmlEncoder::FORMAT); 35 | } 36 | 37 | public function serializeMultiple(array $objects): string 38 | { 39 | $this->checkArrayObjects($objects); 40 | return $this->serializer->serialize($objects, XmlEncoder::FORMAT); 41 | } 42 | 43 | public function unserialize(string $value, string $class): object 44 | { 45 | $decodedValue = $this->checkAndDecodeData($value, $class, XmlEncoder::FORMAT); 46 | return $this->denormalizeObject($decodedValue, $class); 47 | } 48 | 49 | public function unserializeMultiple(string $value, string $class): array 50 | { 51 | $decodedValue = $this->checkAndDecodeData($value, $class, XmlEncoder::FORMAT); 52 | return $this->denormalizeObjects($decodedValue, $class); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/XmlSerializer.php: -------------------------------------------------------------------------------- 1 | serializer = new Serializer([new ObjectNormalizer()], [new XmlEncoder([ 26 | XmlEncoder::ROOT_NODE_NAME => $rootTag, 27 | XmlEncoder::VERSION => $version, 28 | XmlEncoder::ENCODING => $encoding, 29 | ])]); 30 | } 31 | 32 | public function serialize($value): string 33 | { 34 | return $this->serializer->serialize($value, XmlEncoder::FORMAT); 35 | } 36 | 37 | public function unserialize(string $value) 38 | { 39 | return $this->serializer->decode($value, XmlEncoder::FORMAT); 40 | } 41 | } 42 | --------------------------------------------------------------------------------