web-dev-qa-db-ja.com

PHPのオブジェクトでjson_encodeを使用する(スコープに関係なく)

オブジェクトのリストをjsonとして出力しようとしていますが、json_encodeでオブジェクトを使用できるようにする方法があるかどうかを知りたいのですが。私が持っているコードは次のようなものです

$related = $user->getRelatedUsers();
echo json_encode($related);

現在、ユーザーの配列を繰り返し処理し、json_encodeの配列に個別にエクスポートして、使用可能なjsonにしています。オブジェクトを反復可能にすることは既に試みましたが、json_encodeはとにかくそれらをスキップするようです。

編集:var_dump();

php > var_dump($a);
object(RedBean_OODBBean)#14 (2) {
  ["properties":"RedBean_OODBBean":private]=>
  array(11) {
    ["id"]=>
    string(5) "17972"
    ["pk_UniversalID"]=>
    string(5) "18830"
    ["UniversalIdentity"]=>
    string(1) "1"
    ["UniversalUserName"]=>
    string(9) "showforce"
    ["UniversalPassword"]=>
    string(32) ""
    ["UniversalDomain"]=>
    string(1) "0"
    ["UniversalCrunchBase"]=>
    string(1) "0"
    ["isApproved"]=>
    string(1) "0"
    ["accountHash"]=>
    string(32) ""
    ["CurrentEvent"]=>
    string(4) "1204"
    ["userType"]=>
    string(7) "company"
  }
  ["__info":"RedBean_OODBBean":private]=>
  array(4) {
    ["type"]=>
    string(4) "user"
    ["sys"]=>
    array(1) {
      ["idfield"]=>
      string(2) "id"
    }
    ["tainted"]=>
    bool(false)
    ["model"]=>
    object(Model_User)#16 (1) {
      ["bean":protected]=>
      *RECURSION*
    }
  }
}

そして、json_encodeから得られるものは次のとおりです。

php > echo json_encode($a);
{}

私はこれだけで終わった:

    function json_encode_objs($item){   
        if(!is_array($item) && !is_object($item)){   
            return json_encode($item);   
        }else{   
            $pieces = array();   
            foreach($item as $k=>$v){   
                $pieces[] = "\"$k\":".json_encode_objs($v);   
            }   
            return '{'.implode(',',$pieces).'}';   
        }   
    }   

それらのオブジェクトで満たされた配列または単一のインスタンスを取り、それらをjsonに変換します。json_encodeの代わりに使用します。私はそれを改善できる場所があると確信していますが、json_encodeが公開されたインターフェースに基づいてオブジェクトを反復するタイミングを検出できることを望んでいました。

71
A. Rager

RedBeanPHP 2.0には、Beanのコレクション全体を配列に変換する一括エクスポート機能があります。これはJSONエンコーダーで機能します。

json_encode( R::exportAll( $beans ) );
8
Gabor de Mooij

オブジェクトのすべてのプロパティはプライベートです。別名...クラスのスコープ外では使用できません。

PHP <5.4の解決策

プライベートオブジェクトと保護オブジェクトのプロパティをシリアル化する場合は、作成するデータ構造でjson_encode()を利用するクラスのJSONエンコード関数insideを実装する必要がありますこの目的。

class Thing {
    ...
    public function to_json() {
        return json_encode(array(
            'something' => $this->something,
            'protected_something' => $this->get_protected_something(),
            'private_something' => $this->get_private_something()                
        ));
    }
    ...
}

PHP> = 5.4のソリューション

新しいJsonSerializableインターフェイスを使用して、json_encodeで使用される独自のJSON表現を提供します

class Thing implements JsonSerializable {
    ...
    public function jsonSerialize() {
        return [
            'something' => $this->something,
            'protected_something' => $this->get_protected_something(),
            'private_something' => $this->get_private_something()
        ];
    }
    ...
}

より詳細な説明

143
jondavidjohn

PHP> = 5.4.0には、オブジェクトをJSONにシリアル化するための新しいインターフェイスがあります: JsonSerializable

オブジェクトにインターフェイスを実装し、json_encodeを使用するときに呼び出されるJsonSerializableメソッドを定義するだけです。

したがって、PHP> = 5.4.0のsolutionは次のようになります。

class JsonObject implements JsonSerializable
{
    // properties

    // function called when encoded with json_encode
    public function jsonSerialize()
    {
        return get_object_vars($this);
    }
}
40
ilanco

次のコードは私のために働いた:

public function jsonSerialize()
{
    return get_object_vars($this);
}
3
user2944142

これについてはまだ言及していませんが、BeanにはgetProperties()という組み込みメソッドがあります。

したがって、それを使用するには:

// What bean do we want to get?
$type = 'book';
$id = 13;

// Load the bean
$post = R::load($type,$id);

// Get the properties
$props = $post->getProperties();

// Print the JSON-encoded value
print json_encode($props);

この出力:

{
    "id": "13",
    "title": "Oliver Twist",
    "author": "Charles Dickens"
}

さらに一歩進んでください。 Beanの配列がある場合...

// An array of beans (just an example)
$series = array($post,$post,$post);

...次に、次のことができます。

  • foreachループで配列をループします。

  • 各要素(Bean)をBeanのプロパティの配列に置き換えます。

したがって、この...

foreach ($series as &$val) {
  $val = $val->getProperties();
}

print json_encode($series);

...これを出力します:

[
    {
        "id": "13",
        "title": "Oliver Twist",
        "author": "Charles Dickens"
    },
    {
        "id": "13",
        "title": "Oliver Twist",
        "author": "Charles Dickens"
    },
    {
        "id": "13",
        "title": "Oliver Twist",
        "author": "Charles Dickens"
    }
]

お役に立てれば!

2
chrisfargen

私は通常、オブジェクトに小さな関数を含めて、配列またはjsonまたはxmlにダンプできるようにします。何かのようなもの:

public function exportObj($method = 'a')
{
     if($method == 'j')
     {
         return json_encode(get_object_vars($this));
     }
     else
     {
         return get_object_vars($this);
     }
}

いずれにしても、get_object_vars()はおそらく役に立つでしょう。

1
Phoenix

私の方法は次のとおりです。

function xml2array($xml_data)
{
    $xml_to_array = [];

    if(isset($xml_data))
    {
        if(is_iterable($xml_data))
        {
            foreach($xml_data as $key => $value)
            {
                if(is_object($value))
                {
                    if(empty((array)$value))
                    {
                        $value = (string)$value;
                    }
                    else
                    {
                        $value = (array)$value;
                    }
                    $value = xml2array($value);
                }
                $xml_to_array[$key] = $value;
            }
        }
        else
        {
            $xml_to_array = $xml_data;
        }
    }

    return $xml_to_array;
}
0
Andrei
$products=R::findAll('products');
$string = rtrim(implode(',', $products), ',');
echo $string;
0
Asahajit