Sleeping Mummy: var_export() and parsable strings

Article directory

  • refer to
  • environment
  • var_export()
      • concept
      • Application scenarios
          • Data persistence
          • debug
      • Function var_export()
  • Custom class
      • __set_state() magic method
      • Set the logic of the __set_state magic method to restore the object
      • Precautions
  • Generic built-in empty class stdClass
      • stdClass
      • Natural support for __set_state()

Reference

Project Description
Search Engine Bing, Google
AI large model Wen Xinyiyan< /strong>, Tongyi Qianwen, iFlytek Spark Cognitive Model, ChatGPT
PHP Official PHP Manual
PHP Official language.oop5 .magic.php
PHP Official function.var-export.php

Environment

Project Description
PHP 5.5.0, 5.6.8, 7.0.0, 7.2.5, 7.4.9 , 8.0.0, 8.2.9
PHP Editor PhpStorm 2023.1.1 (Professional Edition)

var_export()

Concept

var_export() is a built-in function in PHP that converts data into a legal PHP-parsable string. The main purpose of the var_export() function is to generate a string that contains a data and a representation of the data type to which the data belongs, so that it can be subsequently passed eval() function to restore the data.

Application scenarios

Data persistence

var_export() and eval() can be used to implement data persistence because together they provide a way to serialize the data structure into a string and then Method for recreating this data structure when needed. This process can be used to save data in a file or database and then reload and use it later.

Debugging

var_export() produces easy-to-read output that represents the variable’s value and type in valid PHP code, allowing developers to quickly understand the variable’s contents.

Function var_export()

The rough definition of the function var_export() is as follows:

function var_export(
mixed $value,
bool $return = false
): null|string

Where:

Attribute Description
$value This parameter is used to specify variables or data that need to be converted into legal PHP parsable strings.
$return This parameter is used to specify whether the conversion result needs to be returned as the return value of the function. If false (default value), the conversion result will be output directly to the terminal, and the return value of the function will be set to NULL.

Give me a chestnut

<?php


$arr = [1, 2, 3, 4, 5];
print("Array:\
");
var_export($arr);

print("\
\
String:\
");
var_export("Hello World");

print("\
\
Integer type:\
");
var_export(1);

print("\
\
Boolean:\
");
$result = var_export(TRUE, true);
print($result);

print("\
\
Instance object of the built-in general empty class provided by PHP:\
");
var_export(new stdClass());

print("\
\
Instantial object of custom empty class:\
");
class MyClass {<!-- -->};
var_export(new MyClass());

print("\
\
Resource type:\
");
$fp = fopen('./path/to/file', 'r');
var_export($fp);

Execution effect

Array:
array (
  0 => 1,
  1 => 2,
  2 => 3,
  3 => 4,
  4 => 5,
)

String:
'Hello World'

Integer type:
1

Boolean type:
true

Instantiation objects of built-in general empty classes provided by PHP:
(object) array(
)

Instantiation object of custom empty class:
MyClass::__set_state(array(
))

Resource Type:
NULL

Custom class

__set_state() magic method

When the var_export() function handles a custom object, it will try to convert the object into a form such as

The class to which the object being processed belongs::__set_state(array(
   'Attribute 1' => 'Attribute value 1',
   'Attribute 2' => 'Attribute value 2',
))

String. When restoring the object through the eval() function, the string will be treated as PHP code for execution and the static magic method __set_state() will be transfer. The associative array composed of attributes and attribute values will be used as parameters of the __set_state() method to specify the logic of restoring the object. If you attempt to use the eval() function to restore a parsable string to an object that does not define a __set_state() method, PHP will throw a Fatal Error exception for this purpose. For this, please refer to the following example:

<?php


classMyClass
{<!-- -->
    public $name = "RedHeart";
    public $age = 18;
    public $nation = "China";
}

$indicate_text = var_export(new MyClass(), true);
print($indicate_text . "\
");

# Attempt to restore a parsable string to an object via eval
$result = eval('return ' . $indicate_text . ';');
print_r($result);

In the above example code, in order to return the execution result of $inidicate_text as the return value of the eval function, we combine $indicate_text with return statement for splicing, and since the parameters of the eval() function must be legal parsable PHP code, we also add $indicate_text has a semicolon spliced at the end.

Execution effect

Use the eval() function to restore the parsable string generated by the var_export() function to the original object. The class to which the object belongs needs to implement __set_state() magic method. Otherwise, PHP will throw a Fatal Error exception and terminate immediately.

MyClass::__set_state(array(
   'name' => 'RedHeart',
   'age' => 18,
   'nation' => 'China',
))
PHP Fatal error: Uncaught Error: Call to undefined method MyClass::__set_state() in C:\test.php(15) : eval()'d code:1
Stack trace:
#0 C:\test.php(15): eval()
#1 {main}
  thrown in C:\test.php(15) : eval()'d code on line 1

Set the logic of the __set_state magic method to restore the object

The __set_state() magic method will be able to restore the original object through the property information of the original object provided by var_export(). For this, please refer to the following example:

<?php


classMyClass
{<!-- -->
    static function __set_state($obj_details) {<!-- -->
        # Instantiate the self-generated object into an object
        $obj = new self();
        # Loop through the array composed of the attribute information of the original object
        foreach($obj_details as $key => $value) {<!-- -->
            # Use the keys in the associative array as attributes of the object,
            # value as the attribute value of the corresponding attribute.
            $obj -> $key = $value;
        }
        #Return the restored object as the return value
        return $obj;
    }
}

$myClass = new MyClass();

$myClass -> name = "RedHeart";
$myClass -> age = 19;
$myClass -> nation = "China";

# Get the parsable string of the object through var_export(?, true) and output it to the terminal
$indicate_text = var_export($myClass, true);
print($indicate_text . "\
");

#Restore the original object and output the object's structure to the terminal
$result = eval('return ' . $indicate_text . ";");
var_dump($result);

Execution effect

MyClass::__set_state(array(
   'name' => 'RedHeart',
   'age' => 19,
   'nation' => 'China',
))
object(MyClass)#2 (3) {<!-- -->
  ["name"]=>
  string(8) "RedHeart"
  ["age"]=>
  int(19)
  ["nation"]=>
  string(5) "China"
}

Notes

In the process of persisting and restoring object data through the cooperation of var_export() and eval(), the var_export() function does not It does not have to exist. If you know more about the output information of the var_export function, you can construct the required string by yourself to achieve data persistence of the object.
When the eval() function uses the attribute information of the original object to restore the object, needs to call the __set_state() method of the owning class, which means that the class to which the restored object belongs must be restored before trying to restore the object. Define.
Calling the __set_state() method to restore the object has nothing to do with the instance object of the class (it can be done when the class is not instantiating any objects), so the __set_state() method needs to be set as a static method. Otherwise, PHP will throw a Fatal Error exception and stop running immediately.

For the process of persisting and restoring object data using the combination of var_export() and eval(), the matters needing attention are summarized as follows:

  1. The var_export() function is not the only way of obtaining a parsable string for an object.
  2. The class of the object being restored must be defined before attempting to restore the object.
  3. The __set_state() magic method must be defined as a static method.

Give me a chestnut

<?php


classMyClass
{<!-- -->
    static function __set_state($obj_details) {<!-- -->
        $obj = new self();
        foreach($obj_details as $key => $value) {<!-- -->
            $obj -> $key = $value;
        }
        return $obj;
    }
}

#Parseable string of custom object
$indicate_text = "MyClass::__set_state(array(
                    'name' => 'RedHeart',
                    'age' => 19,
                    'nation' => 'China',
                   ))";

$result = eval('return ' . $indicate_text . ";");
var_dump($result);

Execution effect

object(MyClass)#1 (3) {<!-- -->
  ["name"]=>
  string(8) "RedHeart"
  ["age"]=>
  int(19)
  ["nation"]=>
  string(5) "China"
}

General built-in empty class stdClass

stdClass

stdClass is a base class provided by PHP, which is used to create an empty object without predefined structure (no members are defined in stdClass). The structure of stdClass is roughly as follows:

class stdClass {<!-- -->}

stdClass provides a way to allow developers to create and manage object properties dynamically at runtime without having to define a complete class in advance. For this, please refer to the following example:

<?php


// stdClass belongs to the basic class of PHP,
// It is part of PHP and can be used directly.
$myClass = new stdClass();

//Dynamicly create and manage properties during PHP running
$myClass -> name = "RedHeart";
$myClass -> nation = "BinaryMoon";
$myClass -> nation = "China";

print_r($myClass);

Execution effect

stdClassObject
(
    [name] => RedHeart
    [nation] => China
)

Native support for __set_state()

Although PHP’s built-in class stdClass is an empty class, it has natural support for the __set_state() magic method (PHP has internally provided a __set_state implementation for stdClass instance objects). For this, please refer to the following example:

<?php


$myClass = new stdClass();

# Get the method list of stdClass instance object and output it
print_r(get_class_methods($myClass));

# Define the parsable string of the stdClass instance object
$indicate_text = "(object)array(
                    'name' => 'RedHeart',
                    'age' => 19,
                    'nation' => 'China',
                   )";

# Try to restore the stdClass object through the eval() function
$result = eval('return ' . $indicate_text . ';');
print_r($result);

Execution effect

It can be seen from the execution results of the above example code that even if stdClass does not define the __set_state method, this method can be successfully called and perform the function of restoring the object.

Array
(
)
stdClassObject
(
    [name] => RedHeart
    [age] => 19
    [nation] => China
)