serialize() вместо var_export()

+11
1.23K

Несколько раз встречал на форуме вопросы про Warning: var_export does not handle circular references ... Но странное дело, что пользователь, которому было что-то нужно, поняв, что придется приложить какие-то усилия, исчезал из темы.
Скажу сразу: Я не открыл тайну var_export(), но предложу некий обходной манёвр.

Сейчас при кешировании на файлах работают функции var_export(), чтобы представить нужный массив в виде кода PHP, этот код пишется в файл. Затем, когда этот код нужно загрузить(взять из кеша), применяется include().
Пара слов о циклических ссылках. Это когда какой-то элемент массива ссылается на сам массив(определение не исчерпывающее). И сразу пример

  1.  
  2. <?php
  3. $data = [
  4. 'ttl' => 300,
  5. 'time' => time(),
  6. 'value' => null
  7. ];
  8. $s = var_export($data, true);// преобразуем массив в строку
  9. echo $s;
  10.  
  11. $data["value"] = &$data; // элемент массива ссылается на сам массив
  12. $s = var_export($data, true);// тот самый warning
  13. echo $s; // $data['value'] => null
  14.  

var_export() не единственный способ «упаковать» в строку значение переменной, есть ещё serialize(). Посмотрим, как ведет себя serialize() при наличии циклических ссылок

  1.  
  2. <?php
  3. $data = [
  4. 'ttl' => 300,
  5. 'time' => time(),
  6. 'value' => null
  7. ];
  8. $s = serialize($data); // преобразуем массив в строку
  9. echo $s."\n";
  10.  
  11. $data["value"] = &$data;// элемент массива ссылается на сам массив
  12. $s = serialize($data); // ошибки нет
  13. echo $s."\n"; // в 'value' - сам массив
  14.  
  15. $newData = unserialize($s);// ошибки нет
  16.  

Проблем с циклическими ссылками нет.
Вдохновлённый этими несложными опытами, я переписал несколько строк из /system/core/cachefiles.php, включил Кеширование в админке и оно у меня работает. Моя маленькая хитрость заключается в том, что я совершенно не изменил логики, заложенной разработчиком. Я лишь изменил формат, которым данные записываются в файл, но этот формат «не боится» циклических ссылок.

Теперь краткая инструкция для тех, кто столкнулся с Warning: var_export does not handle circular references или просто хочет попробовать.
— Отключите кеширование в админке, это очистит /cache/data/
— Замените /system/core/cachefiles.php этим файлом
— Включите кеширование в админке
Надеюсь, что это будет работать!
---
UPD 11.04.2021: Случайно наткнулся на этот коммит. laugh
UPD 12.04.2021: После выхода сегодня InstantCMS 2.14.2 статья теряет свою актуальность, потому как в новости о релизе сказано

Кэш на файлах теперь посредством serialize/unserialize;

+1
Dark Space Dark Space 3 года назад #
Блоги пишет и на форуме людям помогает +
0
IamB IamB 2 года назад #

Нечаянно наткнулся на Warning: var_export does not handle circular references. Получить это предупреждение можно если выполнить var_export($fields)
в /templates/modern/controllers/users/profile_view.tpl.php

Еще от автора

Google Таблицы
Поле призвано упростить работу с таблицами. Можно создавать таблицы во встроенном визуальном редакторе, но это занятие как минимум трудоемкое.
Создание таск-трекера своими(почти) руками
Этот пост появился благодаря теме на форуме. Поразмышлял, пописал код, поставил опыты и. думаю, процентов на 80 решил задачу с форума.
Логгер для проекта
По случаю написал логгер. Конечно, можно было взять готовый, поскольку только ленивые их не писали.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.