PHP 객체를 연관 배열로 변환


760

코드를 배열을 사용하여 작성하는 동안 객체에 저장된 데이터로 작동하는 API를 웹 사이트에 통합하고 있습니다.

객체를 배열로 변환하는 빠르고 더러운 기능을 원합니다.

답변:


1392

그냥 캐스트

$array = (array) $yourObject;

에서 배열 :

객체가 배열로 변환되면 결과는 요소가 객체의 속성 인 배열입니다. 키는 몇 가지 예외를 제외하고 멤버 변수 이름입니다. 정수 특성에 액세스 할 수 없습니다. 개인 변수는 클래스 이름 앞에 변수 이름이 붙습니다. 보호 된 변수는 변수 이름 앞에 '*'가 붙습니다. 이 앞에 붙은 값은 양쪽에 널 바이트가 있습니다.

예 : 단순 객체

$object = new StdClass;
$object->foo = 1;
$object->bar = 2;

var_dump( (array) $object );

산출:

array(2) {
  'foo' => int(1)
  'bar' => int(2)
}

예 : 복합 객체

class Foo
{
    private $foo;
    protected $bar;
    public $baz;

    public function __construct()
    {
        $this->foo = 1;
        $this->bar = 2;
        $this->baz = new StdClass;
    }
}

var_dump( (array) new Foo );

출력 (명확성을 위해 편집 된 \ 0) :

array(3) {
  '\0Foo\0foo' => int(1)
  '\0*\0bar' => int(2)
  'baz' => class stdClass#2 (0) {}
}

var_export대신에 출력 var_dump:

array (
  '' . "\0" . 'Foo' . "\0" . 'foo' => 1,
  '' . "\0" . '*' . "\0" . 'bar' => 2,
  'baz' =>
  stdClass::__set_state(array(
  )),
)

이 방법으로 타입 캐스팅을 수행하면 객체 그래프를 딥 캐스팅하지 않으며 (공개 견적에 설명 된대로) 널 바이트를 적용하여 비공개 속성에 액세스해야합니다. 따라서 이것은 StdClass 객체 또는 공용 속성 만있는 객체를 캐스팅 할 때 가장 효과적입니다. 빠르고 더러운 (요청 한 것) 괜찮습니다.

이 심층 블로그 게시물도 참조하십시오.


3
또한 ArrayAccess이 솔루션과 함께 인터페이스를 고려하십시오 . php.net/manual/en/class.arrayaccess.php
alttag

3
정수 키가있어 문자열로 변환되어 큰 문제가 발생할 수 있습니다. 예를 [1 => "one"]하게["1" => "one"]
올렉

2
@Howie와 타입 캐스팅 (array)(object)안정적으로 작품과 PHP 4.3 이후의 모든 버전에서 동일한. 3v4l.org/X6lhm을 참조하십시오 . 구문 오류가 발생하면 문제가있는 것입니다.
Gordon

2
@Howie에 대한 변경 로그 섹션을empty 참조하십시오 . empty5.5 이전 의 표현식은 사용할 수 없습니다 . 이것은 typecasting과는 전혀 관련이 없습니다;)
Gordon

4
캐스트. 예. Freakin CAST를 입력하십시오! 좋은. +1
Kaushik Makwana

346

JSON 인코딩 / 디코딩 함수의 동작에 의존하여 깊이 중첩 된 객체를 연관 배열로 빠르게 변환 할 수 있습니다.

$array = json_decode(json_encode($nested_object), true);

12
당신은 (그리고 물론 내 청춘의 나쁜 성능을 마음) 전체 깊이 재귀 전환을하려는 경우 가장 좋은 솔루션입니다
줄리안 Habekost

2
이것은 내 상황에 완전히 도움이되었습니다. 정말 감사합니다.
Cesar Bielich

9
각각은 여전히 ​​작동한다고 생각합니다. 두 번째 매개 변수를 true로 설정하는 것을 잊지 마십시오.
Kirk B

3
두 번째 매개 변수는 PHP 5.6.25에서 작동하여 문제를 해결했습니다. 감사!
Ju Oliveira

3
중첩 된 객체에 적합합니다! 감사!
Melody

68

" PHP 오브젝트에 대한 첫 번째 Google 히트 에서 assoc 배열 "에 이르기까지

function object_to_array($data)
{
    if (is_array($data) || is_object($data))
    {
        $result = array();
        foreach ($data as $key => $value)
        {
            $result[$key] = object_to_array($value);
        }
        return $result;
    }
    return $data;
}

소스는 codesnippets.joyent.com에 있습니다.


16
개인적으로, 나는 모든 가치에 대한 기능을 상기시키는 아이디어를 좋아하지 않습니다. 비슷한 버전이지만 3 줄로 표시됩니다. function objectToArray($o) { $a = array(); foreach ($o as $k => $v) $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v; return $a; }이것은 객체 또는 배열이 아닌 것을 설정하고 필요한 경우가 아니라면 메소드를 반복적으로 호출하지 않고 계속됩니다.
SpYk3HH

13
@ SpYk3HH : 나만의 답을 쓰시겠습니까?
DanMan

2
"php 배열에서 assoc 배열"에 대한 첫 번째 히트는 stackoverflow.com/questions/4345554/…
Chris

이 (및 @ SpYk3HH의 버전)는 json_encode 옵션 ( stackoverflow.com/a/16111687/470749 ) 보다 나에게 훨씬 느린 것으로 보입니다 . 이러한 접근 방식이 왜 바람직한 지 모르겠습니다.
Ryan

1
@Ryan json 인 코드 및 디코드는 float의 NaN 및 INFINITE 값에서 작동하지 않으며 잠재적으로 내 머리 꼭대기에서 생각할 수없는 다른 문제가있을 수 있지만 많은 경우 더 나은 옵션 일 수 있습니다. 최적화와 관련하여 필요한 것은 컨텍스트 입니다. 이 주제에 대해 작성한 글 evidentlycube.com/blog/game-optimization/when-to-optimize를 연결해 보겠습니다 . tl; dr는 전체 응용 프로그램의 맥락에서 이점이 의미가 없기 때문에 실행 시간이 많이 걸리지 않는 것을 최적화하지 마십시오.
Maurycy

61

객체 속성이 공개 인 경우 다음을 수행 할 수 있습니다.

$array =  (array) $object;

개인용이거나 보호 된 경우 어레이에 이상한 키 이름이 있습니다. 따라서이 경우 다음 기능이 필요합니다.

function dismount($object) {
    $reflectionClass = new ReflectionClass(get_class($object));
    $array = array();
    foreach ($reflectionClass->getProperties() as $property) {
        $property->setAccessible(true);
        $array[$property->getName()] = $property->getValue($object);
        $property->setAccessible(false);
    }
    return $array;
}

속성이 보호 된 경우 setAccessible (false) 속성이 보호 된 가시성으로 다시 변경됩니까? 아니면 사적인가?
Nick Mitchell

내가 찾은 유일한 해결책은 보호 된 속성으로 작동했습니다. 감사합니다
dav

3
개인 및 보호 변수를위한 최고의 솔루션 !!
HIRA THAKUR

여기 $ property-> setAccessible (false); 모든 속성에 대해 실행됩니다 - 그것은 ... 대중 경우에도
프랑소와 부르주아에게

훌륭합니다 ... 굉장합니다 ... 굉장합니다. 감사.
Farid Abbas

14
class Test{
    const A = 1;
    public $b = 'two';
    private $c = test::A;

    public function __toArray(){
        return call_user_func('get_object_vars', $this);
    }
}

$my_test = new Test();
var_dump((array)$my_test);
var_dump($my_test->__toArray());

산출

array(2) {
    ["b"]=>
    string(3) "two"
    ["Testc"]=>
    int(1)
}
array(1) {
    ["b"]=>
    string(3) "two"
}

1
이 솔루션의 장단점은? 클래스 Test로 선언 된 클래스는 어떻습니까 {const A = 1; 공개 $ parent = new Test (); }
Matteo Gaggiano

13

다음은 몇 가지 코드입니다.

function object_to_array($data) {
    if ((! is_array($data)) and (! is_object($data)))
        return 'xxx'; // $data;

    $result = array();

    $data = (array) $data;
    foreach ($data as $key => $value) {
        if (is_object($value))
            $value = (array) $value;
        if (is_array($value))
            $result[$key] = object_to_array($value);
        else
            $result[$key] = $value;
    }
    return $result;
}

나를 위해 가장 잘 작동합니다 (그러나 'xxx'를 제거하고 $ 데이터를 반환해야했습니다)
Gerfried

12

여기에 게시 된 다른 모든 답변은 공용 속성으로 만 작동합니다. 리플렉션과 게터를 사용하여 JavaBeans 와 같은 객체 와 함께 작동하는 솔루션은 다음과 같습니다 .

function entity2array($entity, $recursionDepth = 2) {
    $result = array();
    $class = new ReflectionClass(get_class($entity));
    foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
        $methodName = $method->name;
        if (strpos($methodName, "get") === 0 && strlen($methodName) > 3) {
            $propertyName = lcfirst(substr($methodName, 3));
            $value = $method->invoke($entity);

            if (is_object($value)) {
                if ($recursionDepth > 0) {
                    $result[$propertyName] = $this->entity2array($value, $recursionDepth - 1);
                }
                else {
                    $result[$propertyName] = "***";  // Stop recursion
                }
            }
            else {
                $result[$propertyName] = $value;
            }
        }
    }
    return $result;
}

그러나 ... ... Object / Array를 변수로 사용하는 경우이 모든 것이 이끄는 것입니다. 왜 public속성 이외의 다른 것이 필요한 가요?
SpYk3HH

@ SpYk3HH : 질문하지 않았습니다. 나는 왜 누군가가 처음에 객체보다 배열을 선호하는지조차 모른다.
프랑소와 부르주아

예를 들어, "반복"해야하는 앱에서 대부분의 다른 것은 배열 인 경향이 있기 때문에 루핑을 위해 균일 한 "목록"을 제공하기 위해 쿼리 결과를 배열로 변환하는 것을 선호합니다. "범용 루프 방법"을 쉽게 작성할 수 있습니다. 종종 객체를 사용하는 경우 속성을 반복하지 않고 객체로 사용하고 필요에 따라 해당 속성을 사용합니다.
SpYk3HH

11

무엇에 대해 get_object_vars($obj)? 객체의 공용 속성에만 액세스하려는 경우 유용합니다.

get_object_vars를 참조하십시오 .


10

객체를 배열로 캐스트하십시오.

$arr =  (array) $Obj;

문제를 해결할 것입니다.


5
아니요, 개인 또는 보호 속성이있는 경우에는 적용되지 않습니다.
forsberg

2
가장 간단한 솔루션. 감사합니다
ASD

6

우선, 객체의 배열이 필요한 경우 데이터를 먼저 배열로 구성해야합니다. 생각 해봐

foreach명령문 또는 JSON 변환을 사용하지 마십시오 . 이것을 계획하고 있다면 다시 한 번 개체가 아닌 데이터 구조를 사용하는 것입니다.

실제로 필요한 경우 객체 지향 접근 방식을 사용하여 깨끗하고 유지 관리 가능한 코드를 만드십시오. 예를 들면 다음과 같습니다.

배열로서의 객체

class PersonArray implements \ArrayAccess, \IteratorAggregate
{
    public function __construct(Person $person) {
        $this->person = $person;
    }
    // ...
 }

모든 속성이 필요한 경우 전송 객체를 사용하십시오.

class PersonTransferObject
{
    private $person;

    public function __construct(Person $person) {
        $this->person = $person;
    }

    public function toArray() {
        return [
            // 'name' => $this->person->getName();
        ];
    }

 }

6

이 기능을 쉽게 사용하여 결과를 얻을 수 있습니다.

function objetToArray($adminBar){
    $reflector = new ReflectionObject($adminBar);
    $nodes = $reflector->getProperties();
    $out = [];
    foreach ($nodes as $node) {
        $nod = $reflector->getProperty($node->getName());
        $nod->setAccessible(true);
        $out[$node->getName()] = $nod->getValue($adminBar);
    }
    return $out;
}

PHP 5 이상을 사용하십시오 .


5

다음은 PHP 객체를 연관 배열로 변환하는 재귀 PHP 함수입니다.

// ---------------------------------------------------------
// ----- object_to_array_recursive --- function (PHP) ------
// ---------------------------------------------------------
// --- arg1: -- $object  =  PHP Object         - required --
// --- arg2: -- $assoc   =  TRUE or FALSE      - optional --
// --- arg3: -- $empty   =  '' (Empty String)  - optional --
// ---------------------------------------------------------
// ----- Return: Array from Object --- (associative) -------
// ---------------------------------------------------------

function object_to_array_recursive($object, $assoc=TRUE, $empty='')
{
    $res_arr = array();

    if (!empty($object)) {

        $arrObj = is_object($object) ? get_object_vars($object) : $object;

        $i=0;
        foreach ($arrObj as $key => $val) {
            $akey = ($assoc !== FALSE) ? $key : $i;
            if (is_array($val) || is_object($val)) {
                $res_arr[$akey] = (empty($val)) ? $empty : object_to_array_recursive($val);
            }
            else {
                $res_arr[$akey] = (empty($val)) ? $empty : (string)$val;
            }
            $i++;
        }
    }
    return $res_arr;
}

// ---------------------------------------------------------
// ---------------------------------------------------------

사용 예 :

// ---- Return associative array from object, ... use:
$new_arr1 = object_to_array_recursive($my_object);
// -- or --
// $new_arr1 = object_to_array_recursive($my_object, TRUE);
// -- or --
// $new_arr1 = object_to_array_recursive($my_object, 1);


// ---- Return numeric array from object, ... use:
$new_arr2 = object_to_array_recursive($my_object, FALSE);

3
.. 또는 oneliner :$new_arr1 = (array) $my_object;
FooBar

1
oneliner 버전은 얕기 때문에 동일하지 않습니다.
Jonathan Lidbeck

5

객체를 배열로 변환하려면 명시 적으로 캐스팅하십시오.

$name_of_array = (array) $name_of_object;

5

PHP에서 객체 배열을 변환하는 함수를 만들 수도 있습니다.

function object_to_array($object) {
    return (array) $object;
}

@ Akintunde-Rotimi, 나는 일반적인 기능을 만들고 보여주었습니다.
Rakhi Prajapati

4

데이터베이스에서 데이터를 오브젝트로 얻을 때이를 수행 할 수 있습니다.

// Suppose 'result' is the end product from some query $query

$result = $mysqli->query($query);
$result = db_result_to_array($result);

function db_result_to_array($result)
{
    $res_array = array();

    for ($count=0; $row = $result->fetch_assoc(); $count++)
        $res_array[$count] = $row;

    return $res_array;
}

2
1 또는 10, 41이 아닌 41 개의 업 보트가 허용 된 답변이 있습니다. 귀하의 답변에 무엇이 추가됩니까?
Yaroslav

4

stdClass를 배열로 변환하는 사용자 정의 함수 :

function objectToArray($d) {
    if (is_object($d)) {
        // Gets the properties of the given object
        // with get_object_vars function
        $d = get_object_vars($d);
    }

    if (is_array($d)) {
        /*
        * Return array converted to object
        * Using __FUNCTION__ (Magic constant)
        * for recursive call
        */
        return array_map(__FUNCTION__, $d);
    } else {
        // Return array
        return $d;
    }
}

Array를 stdClass로 변환하는 또 다른 사용자 정의 함수 :

function arrayToObject($d) {
    if (is_array($d)) {
        /*
        * Return array converted to object
        * Using __FUNCTION__ (Magic constant)
        * for recursive call
        */
        return (object) array_map(__FUNCTION__, $d);
    } else {
        // Return object
        return $d;
    }
}

사용 예 :

// Create new stdClass Object
$init = new stdClass;

// Add some test data
$init->foo = "Test data";
$init->bar = new stdClass;
$init->bar->baaz = "Testing";
$init->bar->fooz = new stdClass;
$init->bar->fooz->baz = "Testing again";
$init->foox = "Just test";

// Convert array to object and then object back to array
$array = objectToArray($init);
$object = arrayToObject($array);

// Print objects and array
print_r($init);
echo "\n";
print_r($array);
echo "\n";
print_r($object);

4

사용하다:

function readObject($object) {
    $name = get_class ($object);
    $name = str_replace('\\', "\\\\", $name); \\ Outcomment this line, if you don't use
                                              \\ class namespaces approach in your project
    $raw = (array)$object;

    $attributes = array();
    foreach ($raw as $attr => $val) {
        $attributes[preg_replace('('.$name.'|\*|)', '', $attr)] = $val;
    }
    return $attributes;
}

특수 문자와 클래스 이름이없는 배열을 반환합니다.


4

이 답변은이 게시물의 여러 답변을 통합 한 것입니다. 단순한 값 또는 배열을 가진 공용 또는 개인 속성을 가진 PHP 객체를 연관 배열로 변환하는 솔루션입니다 ...

function object_to_array($obj)
{
    if (is_object($obj))
        $obj = (array)$this->dismount($obj);
    if (is_array($obj)) {
        $new = array();
        foreach ($obj as $key => $val) {
            $new[$key] = $this->object_to_array($val);
        }
    }
    else
        $new = $obj;
    return $new;
}

function dismount($object)
{
    $reflectionClass = new \ReflectionClass(get_class($object));
    $array = array();
    foreach ($reflectionClass->getProperties() as $property) {
        $property->setAccessible(true);
        $array[$property->getName()] = $property->getValue($object);
        $property->setAccessible(false);
    }
    return $array;
}

3

"웰 크원"코드에 대한 일부 개선

/*** mixed Obj2Array(mixed Obj)***************************************/ 
static public function Obj2Array($_Obj) {
    if (is_object($_Obj))
        $_Obj = get_object_vars($_Obj);
    return(is_array($_Obj) ? array_map(__METHOD__, $_Obj) : $_Obj);   
} // BW_Conv::Obj2Array

함수가 클래스의 멤버 (위 등) 인 경우 변경해야하는 사항 __FUNCTION____METHOD__


3

또한 Symfony Serializer 구성 요소를 사용할 수 있습니다

use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;

$serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
$array = json_decode($serializer->serialize($object, 'json'), true);

3

"장식 자"또는 "날짜 모델 변환"패턴을 사용하는 것이 옳고 아름다웠습니다. 예를 들면 다음과 같습니다.

당신의 모델

class Car {
    /** @var int */
    private $color;

    /** @var string */
    private $model;

    /** @var string */
    private $type;

    /**
     * @return int
     */
    public function getColor(): int
    {
        return $this->color;
    }

    /**
     * @param int $color
     * @return Car
     */
    public function setColor(int $color): Car
    {
        $this->color = $color;
        return $this;
    }

    /**
     * @return string
     */
    public function getModel(): string
    {
        return $this->model;
    }

    /**
     * @param string $model
     * @return Car
     */
    public function setModel(string $model): Car
    {
        $this->model = $model;

        return $this;
    }

    /**
     * @return string
     */
    public function getType(): string
    {
        return $this->type;
    }

    /**
     * @param string $type
     * @return Car
     */
    public function setType(string $type): Car
    {
        $this->type = $type;

        return $this;
    }
}

데코레이터

class CarArrayDecorator
{
    /** @var Car */
    private $car;

    /**
     * CarArrayDecorator constructor.
     * @param Car $car
     */
    public function __construct(Car $car)
    {
        $this->car = $car;
    }

    /**
     * @return array
     */
    public function getArray(): array
    {
        return [
            'color' => $this->car->getColor(),
            'type' => $this->car->getType(),
            'model' => $this->car->getModel(),
        ];
    }
}

용법

$car = new Car();
$car->setType('type#');
$car->setModel('model#1');
$car->setColor(255);

$carDecorator = new CarArrayDecorator($car);
$carResponseData = $carDecorator->getArray();

더 아름답고 정확한 코드가 될 것입니다.


3

성가신 별 변환 및 제거 :

$array = (array) $object;
foreach($array as $key => $val)
{
    $new_array[str_replace('*_', '', $key)] = $val;
}

아마도 반사를 사용하는 것보다 저렴할 것입니다.


2

@ SpYk3HH의 짧은 솔루션

function objectToArray($o)
{
    $a = array();
    foreach ($o as $k => $v)
        $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v;

    return $a;
}

2

많은 사람들이 객체의 속성에 동적으로 액세스하는 데 문제가 있기 때문에이 질문을 찾으므로 PHP 에서이 작업을 수행 할 수 있음을 지적합니다. $valueRow->{"valueName"}

문맥 상 (가독성을 위해 제거 된 HTML 출력) :

$valueRows = json_decode("{...}"); // Rows of unordered values decoded from a JSON object

foreach ($valueRows as $valueRow) {

    foreach ($references as $reference) {

        if (isset($valueRow->{$reference->valueName})) {
            $tableHtml .= $valueRow->{$reference->valueName};
        }
        else {
            $tableHtml .= " ";
        }
    }
}

2

타입 캐스팅을 사용하면 문제를 해결할 수 있습니다. 반환 객체에 다음 줄을 추가하십시오.

$arrObj = array(yourReturnedObject);

다음을 사용하여 새 키와 값 쌍을 추가 할 수도 있습니다.

$arrObj['key'] = value;

2

특성을 사용하여 객체-어레이 변환 논리를 저장하는 것이 좋습니다. 간단한 예 :

trait ArrayAwareTrait
{
    /**
     * Return list of Entity's parameters
     * @return array
     */
    public function toArray()
    {
        $props = array_flip($this->getPropertiesList());
        return array_map(
            function ($item) {
                if ($item instanceof \DateTime) {
                    return $item->format(DATE_ATOM);
                }
                return $item;
            },
            array_filter(get_object_vars($this), function ($key) use ($props) {
                return array_key_exists($key, $props);
            }, ARRAY_FILTER_USE_KEY)
        );
    }


    /**
     * @return array
     */
    protected function getPropertiesList()
    {
        if (method_exists($this, '__sleep')) {
            return $this->__sleep();
        }
        if (defined('static::PROPERTIES')) {
            return static::PROPERTIES;
        }
        return [];
    }
}

class OrderResponse
{
    use ArrayAwareTrait;

    const PROP_ORDER_ID = 'orderId';
    const PROP_TITLE = 'title';
    const PROP_QUANTITY = 'quantity';
    const PROP_BUYER_USERNAME = 'buyerUsername';
    const PROP_COST_VALUE = 'costValue';
    const PROP_ADDRESS = 'address';

    private $orderId;
    private $title;
    private $quantity;
    private $buyerUsername;
    private $costValue;
    private $address;

    /**
     * @param $orderId
     * @param $title
     * @param $quantity
     * @param $buyerUsername
     * @param $costValue
     * @param $address
     */
    public function __construct(
        $orderId,
        $title,
        $quantity,
        $buyerUsername,
        $costValue,
        $address
    ) {
        $this->orderId = $orderId;
        $this->title = $title;
        $this->quantity = $quantity;
        $this->buyerUsername = $buyerUsername;
        $this->costValue = $costValue;
        $this->address = $address;
    }

    /**
     * @inheritDoc
     */
    public function __sleep()
    {
        return [
            static::PROP_ORDER_ID,
            static::PROP_TITLE,
            static::PROP_QUANTITY,
            static::PROP_BUYER_USERNAME,
            static::PROP_COST_VALUE,
            static::PROP_ADDRESS,
        ];
    }

    /**
     * @return mixed
     */
    public function getOrderId()
    {
        return $this->orderId;
    }

    /**
     * @return mixed
     */
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * @return mixed
     */
    public function getQuantity()
    {
        return $this->quantity;
    }

    /**
     * @return mixed
     */
    public function getBuyerUsername()
    {
        return $this->buyerUsername;
    }

    /**
     * @return mixed
     */
    public function getCostValue()
    {
        return $this->costValue;
    }

    /**
     * @return string
     */
    public function getAddress()
    {
        return $this->address;
    }
}

$orderResponse = new OrderResponse(...);
var_dump($orderResponse->toArray());

1
$Menu = new Admin_Model_DbTable_Menu(); 
$row = $Menu->fetchRow($Menu->select()->where('id = ?', $id));
$Addmenu = new Admin_Form_Addmenu(); 
$Addmenu->populate($row->toArray());

나는이 답변이 교리 (또는 유사한) 기록에 대한 것이라고 가정한다.
nikoskip

1

여기에 나는했습니다 objectToArray () 도 때처럼, 재귀 적 객체와 함께 작동 방법, $objectA포함을 $objectB하는 점 다시에$objectA .

또한 ReflectionClass를 사용하여 출력을 공용 속성으로 제한했습니다. 필요하지 않은 경우 제거하십시오.

    /**
     * Converts given object to array, recursively.
     * Just outputs public properties.
     *
     * @param object|array $object
     * @return array|string
     */
    protected function objectToArray($object) {
        if (in_array($object, $this->usedObjects, TRUE)) {
            return '**recursive**';
        }
        if (is_array($object) || is_object($object)) {
            if (is_object($object)) {
                $this->usedObjects[] = $object;
            }
            $result = array();
            $reflectorClass = new \ReflectionClass(get_class($this));
            foreach ($object as $key => $value) {
                if ($reflectorClass->hasProperty($key) && $reflectorClass->getProperty($key)->isPublic()) {
                    $result[$key] = $this->objectToArray($value);
                }
            }
            return $result;
        }
        return $object;
    }

이미 사용 된 객체를 식별하기 위해이 (추상) 클래스에 보호 속성을 사용하고 $this->usedObjects있습니다. 재귀 중첩 개체가 발견되면 문자열로 대체됩니다 **recursive**. 그렇지 않으면 무한 루프로 인해 실패합니다.


$usedObjects이 시작시 초기화되지 않으므로이 호출을 여러 번 호출하면 이후 호출에서 잘못된 결과가 발생합니다. 또한 마지막에 해제하지 않으므로 객체가 메모리에서 제거되지 않습니다.
HappyDog 2016 년

1

개인 회원이있는 객체에 객체가있는 경우 내 제안이 있습니다.

public function dismount($object) {
    $reflectionClass = new \ReflectionClass(get_class($object));
    $array = array();
    foreach ($reflectionClass->getProperties() as $property) {
        $property->setAccessible(true);
        if (is_object($property->getValue($object))) {
            $array[$property->getName()] = $this->dismount($property->getValue($object));
        } else {
            $array[$property->getName()] = $property->getValue($object);
        }
        $property->setAccessible(false);
    }
    return $array;
}

1

나는 이것을 사용한다 (적절한 키를 가진 재귀 솔루션이 필요하다) :

    /**
     * This method returns the array corresponding to an object, including non public members.
     *
     * If the deep flag is true, is will operate recursively, otherwise (if false) just at the first level.
     *
     * @param object $obj
     * @param bool $deep = true
     * @return array
     * @throws \Exception
     */
    public static function objectToArray(object $obj, bool $deep = true)
    {
        $reflectionClass = new \ReflectionClass(get_class($obj));
        $array = [];
        foreach ($reflectionClass->getProperties() as $property) {
            $property->setAccessible(true);
            $val = $property->getValue($obj);
            if (true === $deep && is_object($val)) {
                $val = self::objectToArray($val);
            }
            $array[$property->getName()] = $val;
            $property->setAccessible(false);
        }
        return $array;
    }

다음 코드의 사용법 예 :

class AA{
    public $bb = null;
    protected $one = 11;

}

class BB{
    protected $two = 22;
}


$a = new AA();
$b = new BB();
$a->bb = $b;

var_dump($a)

이것을 인쇄합니다 :

array(2) {
  ["bb"] => array(1) {
    ["two"] => int(22)
  }
  ["one"] => int(11)
}

객체 배열이있는 객체를 지원하도록 함수를 어떻게 업그레이드 할 수 있습니까?
celsowm
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.