Usando __set_state() en PHP 7

El método mágico __set_state() se activa (no realmente) para las clases exportadas por la función var_export(). El método acepta un único parámetro de tipo de matriz y devuelve un objeto, según la siguiente sinopsis:

static object __set_state(array $properties)

La función var_export() genera o devuelve una representación de cadena analizable de una variable dada. Es algo similar a la función var_dump(), excepto que la representación devuelta es un código PHP válido:

<?php
class User
{
public $name = 'John';
public $age = 34;
private $salary = 4200.00;
protected $identifier = 'ABC';
}
$user = new User();
var_export($user); // outputs string "User::__set_state…"
var_export($user, true); // returns string "User::__set_state…"

Esto da como resultado la siguiente salida:

User::__set_state(array(
‘name’ => ‘John’,
‘age’ => 34,
‘salary’ => 4200.0,
‘identifier’ => ‘ABC’,
))
string(113) «User::__set_state(array(
‘name’ => ‘John’,
‘age’ => 34,
‘salary’ => 4200.0,
‘identifier’ => ‘ABC’,
))»

El uso de la función var_export() en realidad no activa el método set_state() de nuestra clase de usuario. Simplemente produce una representación de cadena de la expresión User :: set_state (array (…)) que podemos registrar, generar o pasar a través de la construcción del lenguaje eval() para su ejecución.
El siguiente código es un ejemplo más robusto que demuestra el uso de eval():

<?php
class User
{
public $name = 'John';
public $age = 34;
private $salary = 4200.00;
protected $identifier = 'ABC';
public static function __set_state($properties)
{
$user = new User();
$user->name = $properties['name'];
$user->age = $properties['age'];
$user->salary = $properties['salary'];
$user->identifier = $properties['identifier'];
return $user;
}
}
$user = new User();
$user->name = 'Mariya';
$user->age = 32;
eval('$obj = ' . var_export($user, true) . ';');
var_dump($obj);

Esto da como resultado la siguiente salida:

object(User)#2 (4) {
["name"]=> string(6) "Mariya"
["age"]=> int(32)
["salary":"User":private]=> float(4200)
["identifier":protected]=> string(3) "ABC"
}

Sabiendo cómo la construcción del lenguaje eval() es muy peligrosa ya que permite la ejecución de código PHP arbitrario, se desaconseja su uso. Por lo tanto, el uso de __set_state() se vuelve cuestionable para cualquier otra cosa que no sea la depuración.

Comparte