Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[VarExporter] a new component to serialize values to plain PHP code #28231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 27, 2018

Conversation

nicolas-grekas
Copy link
Member

@nicolas-grekas nicolas-grekas commented Aug 19, 2018

Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets -
License MIT
Doc PR -

This PR proposes moving what is currently the PhpMarshaller class in the Cache component to a separate component.

This component would provide only one public static method:
VarExporter::export($value, bool &$isStaticValue = null): string.

This method returns $value serialized as plain PHP code. Running this code creates the same exact data structure that $value contained. This is exactly like serialize() and unserialize(), from which all semantics are preserved (__sleep, __wakeup and Serializable).

The reason to use this method vs serialize() or even igbinary is performance: thanks to OPcache, the resulting code is significantly faster and more memory efficient than using unserialize() or igbinary_unserialize().

Unlike var_export(), this works on any serializable PHP value.

It also provides a few improvements over var_export()/serialize():

  • the output is PSR-2 compatible
  • the output can be re-indented without messing up with any \r or \n in the data
  • missing classes throw a ReflectionException instead of being unserialized to a PHP_Incomplete_Class object
  • references involving SplObjectStorage, ArrayObject or ArrayIterator instances are preserved
  • Reflection*, IteratorIterator and RecursiveIteratorIterator classes throw an exception when being serialized (their unserialized version is broken anyway, see https://bugs.php.net/76737.)

@nicolas-grekas nicolas-grekas added this to the next milestone Aug 19, 2018
@nicolas-grekas nicolas-grekas force-pushed the var-exporter branch 3 times, most recently from 335dcc6 to 2bc8313 Compare August 19, 2018 19:39
@tolry
Copy link

tolry commented Aug 20, 2018

since the naming is similar/identical it might be a good idea to distinguish this from the php core function http://php.net/manual/de/function.var-export.php ?

@nicolas-grekas nicolas-grekas force-pushed the var-exporter branch 2 times, most recently from 6d05c08 to 8668202 Compare August 20, 2018 11:36
@nicolas-grekas
Copy link
Member Author

@tolry we have the VarDumper component that provides a better var_dump() function. I think that the VarExporter name conveys what it should: this is a better var_export().

@nicolas-grekas nicolas-grekas force-pushed the var-exporter branch 2 times, most recently from 77d9f7a to e07f116 Compare August 20, 2018 11:51
@tolry
Copy link

tolry commented Aug 20, 2018

@nicolas-grekas I guessed so, just thought it might be easier to grasp, if the explanation mentioned var_export explicitely. Ah, I see it's in there now - did you add it or did I miss it before? 😁

@nicolas-grekas nicolas-grekas force-pushed the var-exporter branch 4 times, most recently from 6114d8f to 81606f9 Compare August 20, 2018 13:55
@nicolas-grekas
Copy link
Member Author

nicolas-grekas commented Aug 20, 2018

@tolry yes, I updated the description.

PR is ready IMHO.

Copy link
Contributor

@sroze sroze left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except these two comments, it looks good to me 👌

Note that it's very likely it will require more maintenance than when it was internal.

use Symfony\Component\VarExporter\Internal\Exporter;
use Symfony\Component\VarExporter\Internal\Reference;
use Symfony\Component\VarExporter\Internal\Registry;
use Symfony\Component\VarExporter\Internal\Values;

/**
* @author Nicolas Grekas <[email protected]>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually put that at the end of the comment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved down

"name": "symfony/var-exporter",
"type": "library",
"description": "A blend of var_export() + serialize() to turn any serializable data structure to plain PHP code",
"keywords": ["export", "serialize"],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add symfony and var-exporter as well, they are the component 💃

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is already in the name of the component, no need to duplicate

4.2.0
-----

* added the component
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-  * added the component
+ * Created the component (extracted `PhpMarshaller` from the `Cache` component)

Could be valuable to give a hint of where it comes from.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PhpMarshaller has never been released, better not give it any existence except in internal history
I'd keep as is :)

@nicolas-grekas
Copy link
Member Author

nicolas-grekas commented Aug 24, 2018

Note that it's very likely it will require more maintenance than when it was internal.

That's why I added more tests for more cases (and fixes) ;)

Comments addressed, thanks for the review.

=====================

The VarExporter component allows exporting any serializable PHP data structure to
plain PHP code. While doing so, it preserves all the semantics associated to the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

associated with


The VarExporter component allows exporting any serializable PHP data structure to
plain PHP code. While doing so, it preserves all the semantics associated to the
serialization mechanism of PHP (`__wakeup`, `__sleep`, `Serializable` esp.)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"esp" can be removed IMHO

Unlike `var_export()`, this works on any serializable PHP value.

It also provides a few improvements over `var_export()`/`serialize()`:
* the output is PSR-2 compatible
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing empty line before the list, and missing ; at the end of each line but the last.

instances are preserved
* `Reflection*`, `IteratorIterator` and `RecursiveIteratorIterator` classes
throw an exception when being serialized (their unserialized version is broken
anyway, see https://bugs.php.net/76737.)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dot outside the parenthesis

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra space after "see"

* PhpMarshaller allows serializing PHP data structures using var_export()
* while preserving all the semantics associated to serialize().
* VarExporter allows serializing PHP data structures to plain PHP code (like var_export())
* while preserving all the semantics associated to serialize() (unlike var_export()).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

associated with

*
* @return string The value exported as PHP code
*
* @throw \Exception When the provided value cannot be serialized
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolas-grekas
Copy link
Member Author

Comments addressed thanks.

@fabpot
Copy link
Member

fabpot commented Aug 27, 2018

Thank you @nicolas-grekas.

@fabpot fabpot merged commit 7831ad7 into symfony:master Aug 27, 2018
fabpot added a commit that referenced this pull request Aug 27, 2018
…lain PHP code (nicolas-grekas)

This PR was merged into the 4.2-dev branch.

Discussion
----------

[VarExporter] a new component to serialize values to plain PHP code

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

This PR proposes moving what is currently the `PhpMarshaller` class in the Cache component to a separate component.

This component would provide only one public static method:
`VarExporter::export($value, bool &$isStaticValue = null): string`.

This method returns `$value` serialized as plain PHP code. Running this code creates the same exact data structure that `$value` contained. This is exactly like `serialize()` and `unserialize()`, from which all semantics are preserved (`__sleep`, `__wakeup` and `Serializable`).

The reason to use this method *vs* `serialize()` or even igbinary is performance: thanks to OPcache, the resulting code is significantly faster and more memory efficient than using `unserialize()` or `igbinary_unserialize()`.

Unlike `var_export()`, this works on any serializable PHP value.

It also provides a few improvements over `var_export()`/`serialize()`:
- the output is PSR-2 compatible
- the output can be re-indented without messing up with any `\r` or `\n` in the data
- missing classes throw a `ReflectionException` instead of being unserialized to a `PHP_Incomplete_Class` object
- references involving `SplObjectStorage`, `ArrayObject` or `ArrayIterator` instances are preserved
- `Reflection*`, `IteratorIterator` and `RecursiveIteratorIterator` classes throw an exception when being serialized (their unserialized version is broken anyway, see  https://bugs.php.net/76737.)

Commits
-------

7831ad7 [VarExporter] a new component to serialize values to plain PHP code
@nicolas-grekas nicolas-grekas deleted the var-exporter branch August 30, 2018 15:24
@nicolas-grekas nicolas-grekas modified the milestones: next, 4.2 Nov 1, 2018
This was referenced Nov 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants