Среди функций в PHP существует функция "var_export()", которая позволяет выводить дампы переменных, массивов и объектов. В отличие от "print_r" и "var_dump()", она возвращает дамп в виде PHP - кода, что позволяет использовать результат выполнения в функции "eval()". В качестве первого аргумента функция принимает переменную, массив или объект. По умолчанию выводиться дамп объекта, а сама функция ничего не возвращает. Но если в качестве второго необязательного параметра передать значение "true", то функция возвратит результат в виде строки.
Использование функции "var_export()" для вывода дампа:
$_myVariable = 'Переменная';
$_myArray = array('Массив_1', array('Массив_2'));
class myExport {
public $_public_1, $_public_2;
function __construct() {
$this->_public_1 = 100;
$this->_public_2 = 1000;
}
}
$_Class_myExport = new myExport();
echo '<pre>';
echo '<div>';
var_export($_myVariable);
echo '</div>';
echo '<div>';
var_export($_myArray);
echo '</div>';
echo '<div>';
var_export($_Class_myExport);
echo '</div>';
echo '</pre>';
Результат:
'Переменная'
array (
0 => 'Массив_1',
1 =>
array (
0 => 'Массив_2',
),
)
myExport::__set_state(array(
'_public_1' => 100,
'_public_2' => 1000,
))
Продемонстрируем пример использования второго, дополнительного параметра функции "var_export()":
$_myResult = var_export($_Class_myExport, true);
echo $_myResult;
Результат:
myExport::__set_state(array( '_public_1' => 100, '_public_2' => 1000, ))
Приведём пример создания копии массива при помощи функции "var_export()":
$_myString = var_export($_myArray, true);
eval('$_myCopy = '. $_myString .';');
echo '<pre>';
print_r($_myCopy);
echo '</pre>';
Как видно, скрипт создаёт копию массива "$_myArray" и помещает её в массив "$_myCopy". Массив воссоздаётся путём динамического выполнения PHP - кода при помощи функции "eval()". Результат:
Array
(
[0] => Массив_1
[1] => Array
(
[0] => Массив_2
)
)
По отношению к объекту функция "var_export()" действует несколько иным образом, поскольку невозможно предугадать заранее код, который бы воспроизводил объект, функция возвращает код вызова специального метода "__set_state()". В качестве единственного параметра методу "__set_state()" передаётся ассоциативный массив со всеми членами объекта.
Приведём пример использования метода "__set_state()", получив значение объекта в массиве:
class myExport {
public $_public_1, $_public_2;
function __construct ($_vars_1, $_vars_2) {
$this->_public_1 = $_vars_1;
$this->_public_2 = $_vars_2;
}
public function __set_state ($_myArray) {
foreach ($_myArray as $_myKey => $_myValue) {
echo '<div>'. $_myKey .' => '. $_myValue .'</div>';
}
}
}
$_Class_myExport = new myExport(10, 15);
# Возвращаем вызов метода "__set_state()";
$_myString = var_export($_Class_myExport, true);
# Вызов метода "__set_state()";
eval($_myString .';');
Результат:
_public_1 => 10
_public_2 => 15
Функция "var_export()" задумывалась для возвращения дампа массива или объекта, который совместно с функцией "eval()" позволяет воспроизвести объект. Поэтому рекомендуется использовать метод "__set_state()" именно для воссоздания объекта, а не для каких - то иных целей.
Приведём альтернативную реализацию класса "myExport", в котором метод "__set_state()" собирает и возвращает новый объект.
class myExport {
public $_public_1, $_public_2;
function __construct ($_vars_1, $_vars_2) {
$this->_public_1 = $_vars_1;
$this->_public_2 = $_vars_2;
}
public function __set_state ($_myArray) {
foreach($_myArray as $_myKey => $_myValue) {
return new myExport($_myArray['_public_1'], $_myArray['_public_2']);
}
}
}
$_Class_myExport = new myExport(111, 225);
$_myString = var_export($_Class_myExport, true);
# Создаём объект "$_Class_newMyExport" - копию объекта "$_Class_myExport" ;
eval('$_Class_newMyExport = '. $_myString .';');
echo '<pre>';
print_r($_Class_newMyExport);
echo '</pre>';
Результат:
myExport Object
(
[_public_1] => 111
[_public_2] => 225
)
Использование приведённой выше методики позволяет обойти ограничение, связанное с присваиванием объектов друг другу, после которого два объекта ссылаются на одну и ту же область памяти. Однако для получения копии объекта существует более удобная методика клонирования.
3345