2011-08-10 93 views
22

我想在JSON編碼PHP中的一些對象,但我面臨一個問題:我想編碼由類私人成員保存的數據。 我發現這段代碼通過調用編碼功能一樣對這個對象進行編碼:PHP json_encode類私人成員

public function encodeJSON() 
{ 
    foreach ($this as $key => $value) 
    { 
     $json->$key = $value; 
    } 
    return json_encode($json); 
} 

然而,這僅僅在進行到編碼我想要的對象不包含內部的其他對象,這是如此。我怎樣才能編碼不僅「外部」的對象,但編碼以及任何成員也是對象?

+0

或者使用公共方法或使用反射 –

+0

你應該接受一個答案。 – Roman

回答

11

無論如何。你需要在你的類中創建public方法返回的所有領域JSON在類的內部編碼

public function getJSONEncode() { 
    return json_encode(get_object_vars($this)); 
} 
+0

這是否工作,如果一些領域反過來有私人變數?我猜它不會,因爲json_encode不能被遞歸調用。 –

+0

http://php.net/manual/en/function.get-object-vars.php中的示例代碼似乎顯示了它的工作方式,因爲它可以訪問其成員。 – ymajoros

1

只能編碼對象的私有成員。但是,請注意,json_enocde函數不適合你嗎? http://php.net/manual/en/function.json-encode.php

+0

是的,從一個類的上下文中起作用。但是,當一些班級成員也是私人成員的對象時,我應該如何繼續? – rrrcass

2

這將打印一個JSON所有foo類的屬性(公共,私有和受保護)的:

$reflection = new ReflectionClass('Foo'); 
$properties = $reflection->getdefaultProperties(); 

echo json_encode($properties); 

它會從任何方面的工作。

41

序列化與私有屬性的對象最好的方法是實現\ JsonSerializable接口,然後實現自己的JsonSerialize方法返回您需要被序列化的數據。

<?php 

class Item implements \JsonSerializable 
{ 
    private $var; 
    private $var1; 
    private $var2; 

    public function __construct() 
    { 
     // ... 
    } 

    public function jsonSerialize() 
    { 
     $vars = get_object_vars($this); 

     return $vars; 
    } 
} 

json_encode現在將正確序列化您的對象。

+0

這應該是被接受的答案。 – Roman

2

使用反射,你可以json_encode私人性質,但其不認爲是最佳做法:

function json_encode_private($object) { 
    $public = []; 
    $reflection = new ReflectionClass($object); 
    foreach ($reflection->getProperties() as $property) { 
     $property->setAccessible(true); 
     $public[$property->getName()] = $property->getValue($object); 
    } 
    return json_encode($public); 
} 

例如

class Foo { 
    public $a = 1; 
    public $b = 2; 
} 
class Bar { 
    private $c = 3; 
    private $d = 4; 
} 

var_dump(json_encode(new Foo())); 
var_dump(json_encode_private(new Bar())); 

輸出:

string(13) "{"a":1,"b":2}" 
string(13) "{"c":3,"d":4}" 

http://codepad.viper-7.com/nCcKYW

3
public function jsonSerialize() 
{ 
    $objectArray = []; 
    foreach($this as $key => $value) { 
     $objectArray[$key] = $value; 
    } 

    return json_encode($objectArray); 
} 

我個人認爲這是做這件事的方式。它與Petah類似,只是它與封裝很好地保持一致,因爲數組是從對象中填充的。

把這個功能在任一對象或爲特質,以你的對象使用。儘管每個人都是自己的。

+0

這樣做沒有意義 - 如果你需要獲得私人股票,Oleg的回答在上面可以正常工作。 –

10

我覺得@佩塔提克瓦的得到了最好的方法,但這樣你失去的是數組或對象的屬性。所以我增加了一個功能至極做遞歸:

function json_encode_private($object) { 

    function extract_props($object) { 
     $public = []; 

     $reflection = new ReflectionClass(get_class($object)); 

     foreach ($reflection->getProperties() as $property) { 
      $property->setAccessible(true); 

      $value = $property->getValue($object); 
      $name = $property->getName(); 

      if(is_array($value)) { 
       $public[$name] = []; 

       foreach ($value as $item) { 
        if (is_object($item)) { 
         $itemArray = extract_props($item); 
         $public[$name][] = $itemArray; 
        } else { 
         $public[$name][] = $item; 
        } 
       } 
      } else if(is_object($value)) { 
       $public[$name] = extract_props($value); 
      } else $public[$name] = $value; 
     } 

     return $public; 
    } 

    return json_encode(extract_props($object)); 
} 

編輯:新增is_object()檢查數組內循環,以避免在未來extract_props一個get_class()異常()調用,當數組元素是不對象,如字符串或數字。

+0

測試/調試大量嵌套對象非常有用。非常感謝:) – Sobakus

+0

這是我找到的具有屬性作爲嵌套對象的對象的第一個答案。這也適用於PHP 5.3.3。謝謝。 1 –

+0

也涵蓋是數組值,則需要一個另外的包裝: 私有靜態函數extract_props_obj_or_array($ objectOrArray){ \t \t 如果\t(is_array($ objectOrArray)){ \t \t \t $結果=陣列(); \t \t \t的foreach($ objectOrArray爲$對象){ \t \t \t \t $導致[] = extract_props($對象); \t \t \t} \t \t \t return $ result; \t \t \t \t \t \t}其他{// 我們現在知道這是不是一個數組.... \t \t \t回extract_props_object($ objectOrArray); \t \t} \t \t} – jfx