2011-12-28 3 views
1

Так что в основном я пытаюсь кодировать объект класса php, который у меня есть, и вставлять его непосредственно в MongoDB. Проблема в том, что мой класс имеет переменную массива, предназначенную для хранения предыдущих версий класса, поэтому эти частные переменные не могут быть доступны с помощью JSON-кодирования. Как я могу обойти это? Пример того, как мой класс устанавливается ниже (это гораздо больше, но это должно помочь вам получить идею)PHP/MongoDB JSON Encode - не удается получить доступ к приватным переменным внутреннего класса при вызове json_encode()

class App { 
    private $version_number = "1.0.1"; 
    private $previous_versions= array(); //each element in the array will be a previous version of the App object 

    public function storeOldVersions(){ 
     $clone = clone $this; 
     array_unshift($this->previous_versions, $clone); 
    } 
} 

Так что я сделать что-то вроде:

$app = new App(); 
$app->storeOldVersions(); 
echo json_encode($app); 

И эхо json_encode правильно показывает данные объекта $ app, но json-кодировка массива $ previous_version пуста, потому что его переменные являются частными. Как я могу исправить это, не открывая переменные каждого объекта приложения?

Спасибо!

+0

Просто небольшая проблема: 'class App() {' должно быть 'class App {'. – mc10

ответ

0

Вы можете попробовать добавить публичный геттер вернуть массив previous_versions:

public function getPreviousVersions() 
{ 
    return $this->previous_versions; 
} 

- Edit -

Я прочитал на РНР документы для json_encode, похоже, кто-то сталкивался с тот же вопрос у вас есть. Зайдите в http://us2.php.net/json_encode и найдите отправку кода «mic dot sumner at gmail dot com» 02-Jul-2010 01:39, похоже, что он придумал специальное решение, чтобы частные пользователи могли быть доступны после вызова json_encode.

+0

У меня уже есть это - но я пытаюсь использовать функцию json_encode –

+0

@ZakRyterman: Кажется, это по дизайну. Если переменная-член имеет частную/защищенную область видимости, почему json_encode нарушит эту область? Вы считали, что serialize() работает. –

+0

Хмм, я проведу сериализацию –

0

Если вы хотите, чтобы получить доступ к json_encodeчастных или защищенных пользователей, нужно, чтобы выставить их в первую очередь. Вы можете сделать это в какой-то вспомогательной функции. Использование:

$app = new App(); 

echo json_encode_private($app), "\n"; 

, которые могли бы затем вывести так:

{"_App_version_number":"1.0.1","_App_previous_versions":{}} 

Этот вариант такой функции довольно голый, он использует простой функции в PHP, чтобы сделать частные и защищенные члены видны:

/** 
* json_encode object including private and protected members 
* 
* @param object $object 
* @return string JSON 
*/ 
function json_encode_private($object) 
{ 
    if (!is_object($object)) 
     throw new InvalidArgumentException('Object type mismatch.'); 

    $json = json_encode((array) $object, JSON_FORCE_OBJECT); 
    $json = preg_replace('~([{,]")\\\\u0000(\w+)\\\\u0000~i', '$1_$2_', $json); 
    $json = preg_replace('~([{,]")\\\\u0000(\*)\\\\u0000~i', '$1_', $json); 

    return $json; 
} 

Он использует регулярное выражение, у меня просто есть другая идея, но сначала мне нужно ее протестировать. Надеюсь, это полезно.

Редактировать: Как это работает?

Листинг в массив (array) сделает частные объекты доступными для json_encode. Поскольку теперь это массив, JSON_FORCE_OBJECT заставит json снова закодировать его как объект.

Регулярные выражения используются для переименования частных и защищенных свойств, поскольку они содержат специальные маркеры NUL-байтов, которые не являются удобными, если вы хотите загрузить объект в javascript.

Поскольку это только регулярное выражение, а не синтаксический анализатор json, аналогичные форматированные данные внутри свойств также будут изменены, но я предполагаю, что это чаще всего не так. Но будьте осторожны.

Кроме того, обратите внимание, что это не работает рекурсивно для сложных объектов с этой версией.

Должно быть возможно расширить это на основе возможностей PHP's Reflection­Docs. Это также позволит фильтровать определенные элементы или типы доступа, а также определять более подробную схему, как эти имена должны быть названы.

+0

похоже, что это мой ответ, хотя я понятия не имею, что происходит на haha. –

+0

@ZakRyterman: Я добавил объяснение, что он делает. – hakre

+0

попробовал, все еще имея проблемы. мой массив previous_versions выглядит как "" _App_previous_versions ": {" 0 ": {}}, –

Смежные вопросы