The VarExporter Component

The VarExporter component exports any serializable PHP data structure toplain PHP code and allows to instantiate and populate objects withoutcalling their constructors.

Installation

  1. $ composer require --dev symfony/var-exporter

Note

If you install this component outside of a Symfony application, you mustrequire the vendor/autoload.php file in your code to enable the classautoloading mechanism provided by Composer. Readthis article for more details.

Exporting/Serializing Variables

The main feature of this component is to serialize PHP data structures to plainPHP code, similar to PHP's var_export function:

  1. use Symfony\Component\VarExporter\VarExporter;
  2.  
  3. $exported = VarExporter::export($someVariable);
  4. // store the $exported data in some file or cache system for later reuse
  5. $data = file_put_contents('exported.php', $exported);
  6.  
  7. // later, regenerate the original variable when you need it
  8. $regeneratedVariable = require 'exported.php';

The reason to use this component instead of serialize() or igbinary isperformance: thanks to OPcache, the resulting code is significantly fasterand more memory efficient than using unserialize() or igbinary_unserialize().

In addition, there are some minor differences:

  • If the original variable defines them, all the semantics associated withserialize() (such as wakeup(), sleep(), and Serializable)are preserved (var_export() ignores them);
  • References involving SplObjectStorage, ArrayObject or ArrayIteratorinstances are preserved;
  • Missing classes throw a ClassNotFoundException instead of beingunserialized to PHP_Incomplete_Class objects;
  • Reflection*, IteratorIterator and RecursiveIteratorIteratorclasses throw an exception when being serialized.The exported data is a PSR-2 compatible PHP file. Consider for example thefollowing class hierarchy:
  1. abstract class AbstractClass
  2. {
  3. protected $foo;
  4. private $bar;
  5.  
  6. protected function setBar($bar)
  7. {
  8. $this->bar = $bar;
  9. }
  10. }
  11.  
  12. class ConcreteClass extends AbstractClass
  13. {
  14. public function __construct()
  15. {
  16. $this->foo = 123;
  17. $this->setBar(234);
  18. }
  19. }

When exporting the ConcreteClass data with VarExporter, the generated PHPfile looks like this:

  1. <?php
  2. return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
  3. $o = [
  4. clone (\Symfony\Component\VarExporter\Internal\Registry::$prototypes['Symfony\\Component\\VarExporter\\Tests\\ConcreteClass'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('Symfony\\Component\\VarExporter\\Tests\\ConcreteClass')),
  5. ],
  6. null,
  7. [
  8. 'Symfony\\Component\\VarExporter\\Tests\\AbstractClass' => [
  9. 'foo' => [
  10. 123,
  11. ],
  12. 'bar' => [
  13. 234,
  14. ],
  15. ],
  16. ],
  17. $o[0],
  18. []
  19. );

Instantiating PHP Classes

The other main feature provided by this component is an instantiator which cancreate objects and set their properties without calling their constructors orany other methods:

  1. use Symfony\Component\VarExporter\Instantiator;
  2.  
  3. // creates an empty instance of Foo
  4. $fooObject = Instantiator::instantiate(Foo::class);
  5.  
  6. // creates a Foo instance and sets one of its properties
  7. $fooObject = Instantiator::instantiate(Foo::class, ['propertyName' => $propertyValue]);
  8.  
  9. // creates a Foo instance and sets a private property defined on its parent Bar class
  10. $fooObject = Instantiator::instantiate(Foo::class, [], [
  11. Bar::class => ['privateBarProperty' => $propertyValue],
  12. ]);

Instances of ArrayObject, ArrayIterator and SplObjectHash can becreated by using the special "\0" property name to define their internal value:

  1. // Creates an SplObjectHash where $info1 is associated to $object1, etc.
  2. $theObject = Instantiator::instantiate(SplObjectStorage::class, [
  3. "\0" => [$object1, $info1, $object2, $info2...]
  4. ]);
  5.  
  6. // creates an ArrayObject populated with $inputArray
  7. $theObject = Instantiator::instantiate(ArrayObject::class, [
  8. "\0" => [$inputArray]
  9. ]);