2011-12-28 6 views
1

基本的に、私が持っているPHPクラスオブジェクトをエンコードしようとしています。それをMongoDBに直接挿入しようとしています。問題は、私のクラスには以前のバージョンのクラスを保持する配列変数があるため、JSONエンコードではそれらのprivate変数にアクセスできません。どうすればこの問題を回避できますか?私のクラスの設定方法の例は、(それははるかに大きいのですが、これはあなたのアイデアを得るのを助ける必要があります)以下であるPHP/MongoDB JSONエンコード - 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オブジェクトのデータを表示しますが、$ prior_version配列のjsonエンコーディングは変数がprivateであるため空白です。これを修正するには、各アプリケーションオブジェクトの変数を公開する必要はありませんか?

ありがとうございます!

+0

ちょっと小さな問題です: 'クラスApp(){'は 'class App {'でなければなりません。 – mc10

答えて

0

あなたはprevious_versions配列を返すために、公共ゲッターを追加してみてくださいすることができます

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

- 編集 - 私はjson_encodeのためのPHPのドキュメントをよく読んで

誰かが出くわしたように、それが見えます同じ問題があります。 http://us2.php.net/json_encodeをチェックし、2010年2月2日01:39の "gmail dot comのマイクドットサムナー"によるコード提出を検索すると、彼はjson_encodeコールの後にプライベートメンバーを利用できるようにするカスタムソリューションを思いついたようです。

+0

私はすでにそれを持っていますが、json_encode関数を使用しようとしています –

+0

@ZakRyterman:これは設計によるものです。メンバ変数にプライベート/プロテクトスコープがある場合、なぜjson_encodeはそのスコープを破るのですか?あなたはserialize()を考えましたか?うまくいくようです。 –

+0

hmm、シリアル化をチェックアウトします –

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

これは私の答えのように見えますが、何が起こっているのか分かりません。 –

+0

@ZakRyterman:私は何をしているのか説明を追加しました。 – hakre

+0

それを試したが、まだ問題がある。私のprevious_versions配列は、 "" _App_previous_versions "のようになります:{" 0 ":{}} –

関連する問題