PHPオブジェクトを連想配列に変換します

2010年12月03日に質問されました。  ·  閲覧回数 1.3M回  ·  ソース

Haroldo picture
2010年12月03日

コードが配列を使用して記述されている間、オブジェクトに格納されたデータを処理するAPIをWebサイトに統合しています。

オブジェクトを配列に変換するための手っ取り早い関数が欲しいのですが。

回答

Gordon picture
2010年12月03日
1471

タイプキャストするだけです

$array = (array) $yourObject;

配列から:

オブジェクトが配列に変換されると、結果は、要素がオブジェクトのプロパティである配列になります。 キーはメンバー変数名ですが、いくつかの注目すべき例外があります。整数プロパティにはアクセスできません。 プライベート変数には、変数名の前にクラス名が付いています。 保護された変数には、変数名の前に「*」が付いています。 これらの付加値には、両側にnullバイトがあります。

例:単純なオブジェクト

$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(
  )),
)

この方法で型キャストしても、オブジェクトグラフのディープキャストは行われず、非公開属性にアクセスするには、nullバイトを適用する必要があります(手動引用で説明されています)。 したがって、これは、StdClassオブジェクトまたはパブリックプロパティのみを持つオブジェクトをキャストする場合に最適に機能します。 速くて汚い(あなたが求めたもの)ためにそれは大丈夫です。

この詳細なブログ投稿も参照してください。

Jeff Standen picture
2013年04月20日
381

JSONエンコード/デコード関数の動作に依存することで、深くネストされたオブジェクトを連想配列にすばやく変換できます。

$array = json_decode(json_encode($nested_object), true);
Maurycy picture
2010年12月03日
73

PHPオブジェクトから連想配列」に対する最初のGoogleヒットから、次のようになります。

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にあります。

Ramon K. picture
2013年04月16日
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;
}
Isius picture
2014年01月09日
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"
}
Khalid picture
2011年09月20日
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;
}
Francois Bourgeois picture
2013年02月05日
12

ここに投稿された他のすべての回答は、パブリック属性でのみ機能します。 これは、リフレクションとゲッターを使用してJavaBeansのようなオブジェクトで機能する1つのソリューションです。

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;
}
Joe picture
2013年12月11日
12

get_object_vars($obj)どうですか? オブジェクトのパブリックプロパティにのみアクセスしたい場合に便利です。

get_object_varsを参照してください。

Adeel picture
2010年12月03日
10

オブジェクトを配列に型キャストします。

$arr =  (array) $Obj;

それはあなたの問題を解決します。

John Smith picture
2016年02月27日
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();
        ];
    }

 }