Статьи

Сериализация структур данных PHP для Javascript

В настоящее время возится с некоторым кодом, который сериализует структуры данных PHP в Javascript и обратно, как средство для легкого обмена данными.

Переход от Javascript к PHP довольно легко сделать (см. Комментарии пользователей на http://www.php.net/serialize ) путем генерации строк, которые PHP способен десериализировать, например;

String.prototype.toPHP=function() { var s = this s=s.replace(/\/g, "\\") s=s.replace(/"/g, "\"") s=s.replace(/n/g, "\n") s=s.replace(/r/g, "") return 's:'+s.length+':"'+s+'";'; }

Это изменяет класс Javascript String, поэтому вы можете вызывать toPHP () для любой строки и получать ее сериализованное PHP-представление.

Пройдя в обратном направлении, с тем, что у меня есть в настоящее время, если у меня есть простой массив PHP вроде;

$a = array('x','y');

«сериализованная» строка, готовая к «распаковке» Javascript, будет;

'new Function('var a = new Array();a[0]="x";a[1]="y";return a');'

Если у меня есть эта строка в переменной Javascript с именем «serializedData» (возможно, полученной через XMLHttpRequest ), я могу использовать ее следующим образом;

// Creates a function object unserializedDataFunc = eval(serializedData);

// Возвращаем данные из объекта функции
unserializedData = unserializedDataFunc ();

Причина использования объекта Function в сочетании с eval () заключается в том, что я могу избежать всех конфликтов имен в Javascript. Не уверен на 100%, что это лучший механизм для «сериализации» структуры данных для Javascript — выход из кавычек может быть головной болью. Это помогает сохранять анонимность до тех пор, пока я не назначу переменную, но у кого-нибудь есть подходы лучше? Я хочу избежать всех форматов XML, между прочим, чтобы иметь как можно меньше «слоев» между PHP и Javascript и поддерживать минимальные накладные расходы, а также простоту работы с ними.

Еще одна сложная вещь — это сопоставление массивов PHP, которые могут быть как индексированными, так и ассоциативными, например;

$a = array('x','y','z','a'=>1,'b'=>2);

Объект Javascript Array отслеживает только проиндексированные элементы — я могу добавить к нему свойства, например

var a = new Array(); a.push('x'); a.push('y'); a.push('z'); a["a"] = 1; a["b"] = 2;

Но мне нужен цикл for для индексированных элементов и цикл for..in для свойств. Соблазнительно реализовать новый класс PHPArray в Javascript, но думаю, что это грозит проблемами. Не уверен, что это действительно проблема, так как вам редко нужно итерировать как индексированные, так и ассоциативные элементы, но если у кого-то есть идея получше, она с удовольствием ее услышит.

Общая миссия здесь, кстати, является простой механизм, чтобы заставить XUL говорить на PHP.