programing

PHP json_encode 클래스 개인 구성원

itsource 2023. 3. 8. 23:05
반응형

PHP json_encode 클래스 개인 구성원

PHP에서 JSON을 인코딩하려고 하는데 문제가 있습니다.클래스 프라이빗 멤버가 보관하고 있는 데이터를 인코딩하고 싶다.다음과 같은 인코딩 함수를 호출하여 이 개체를 인코딩하는 코드 조각을 찾았습니다.

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

단, 부호화할 객체가 내부에 다른 객체가 없는 경우에만 이 기능이 작동합니다."외부" 객체뿐만 아니라 객체인 멤버도 인코딩하려면 어떻게 해야 합니까?

개체를 개인 속성과 함께 직렬화하는 가장 좋은 방법은 \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이제 오브젝트를 올바르게 시리얼화합니다.

php 5.4 를 사용하고 있는 경우는, Json Serializable 인터페이스를 사용할 수 있습니다.

클래스에서 jsonSerialize 메서드를 구현하면 부호화할 내용이 모두 반환됩니다.

그런 다음 개체를 json_encode로 전달하면 jsonSerialize 결과가 인코딩됩니다.

어쨌든, 클래스에서 public 메서드를 생성하여 모든 필드를 반환해야 합니다.json 인코딩된 필드

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

@Petah가 최선의 접근방식을 가지고 있다고 생각합니다만, 그렇게 하면 어레이나 오브젝트의 속성을 잃게 됩니다.그래서 재귀적으로 수행하는 함수를 추가했습니다.

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));
}

편집: 어레이 요소가 문자열이나 숫자 등의 객체가 아닌 경우 다음 extract_props() 호출에서 get_class() 예외를 피하기 위해 어레이 루프 내부에 is_object() 체크가 추가되었습니다.

저는 이것이 특성의 활용에 대한 훌륭한 사례라고 생각합니다.

아래 guist를 사용하여 jsonSerializable interface를 앱의 여러 포인트에 구현하고 코드를 관리할 수 있도록 유지했습니다.

https://gist.github.com/zburgermeiszter/7dc5e65b06bb34a325a0363726fd8e14

trait JsonSerializeTrait
{
    function jsonSerialize()
    {
        $reflect = new \ReflectionClass($this);
        $props   = $reflect->getProperties(\ReflectionProperty::IS_STATIC | \ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED | \ReflectionProperty::IS_PRIVATE);

        $propsIterator = function() use ($props) {
            foreach ($props as $prop) {
                yield $prop->getName() => $this->{$prop->getName()};
            }
        };

        return iterator_to_array($propsIterator());
    }
}

그럼 그냥 하면 돼

class YourClass implements JsonSerializable 
{
    use JsonSerializeTrait;

    ... normal encapsulated code...
}
public function jsonSerialize()
{
    $objectArray = [];
    foreach($this as $key => $value) {
        $objectArray[$key] = $value;
    }

    return json_encode($objectArray);
}

나는 개인적으로 이것이 그것을 하는 방법이라고 생각한다.어레이가 개체에서 채워지기 때문에 캡슐화와 잘 일치한다는 점을 제외하면 Petah와 유사합니다.

이 기능을 오브젝트에 넣거나 오브젝트에서 사용할 특성으로 넣으세요.하지만 각자 제각각이죠.

에 의해, 「」의 , protected 에 됩니다.foo:

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

echo json_encode($properties);

어떤 맥락에서든 작동될 수 있습니다.

클래스 내에서만 개체의 개인 구성원을 인코딩할 수 있습니다.참고로 json_enocde 함수는 작동하지 않습니까?http://php.net/manual/en/function.json-encode.php

을 통해 '반성'을 할 수 .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

언급URL : https://stackoverflow.com/questions/7005860/php-json-encode-class-private-members

반응형