web-dev-qa-db-ja.com

変換する PHP 連想配列へのオブジェクト

私のコードは配列を使って書かれているが、オブジェクトに格納されたデータを扱うAPIを私のウェブサイトに統合している。

オブジェクトを配列に変換するための迅速で汚い関数が欲しいのですが。

625
Haroldo

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

$array =  (array) $yourObject;

からhttp://www.php.net/manual/en/language.types.array.php

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

例:シンプルオブジェクト

$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オブジェクトまたはパブリックプロパティのみを持つオブジェクトをキャストするときに最も効果的です。早くて汚い(あなたが求めたもの)それは結構です。

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

1189
Gordon

JSONのエンコード/デコード機能の動作に依存することで、深くネストしたオブジェクトを連想配列に素早く変換できます。

$array = json_decode(json_encode($nested_object), true);
281
Jeff Standen

最初のグーグルが " phpオブジェクトを連想配列 "にヒットしてから、これがあります

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 にあるソース。

63
Maurycy

オブジェクトのプロパティが公開されている場合は、次の操作を実行できます。

$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;
}
51
ramonztro
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"
}
10
Isius

ここに掲載されている他のすべての回答は、パブリック属性のみを使用しています。これはリフレクションとゲッターを使って javabean - のようなオブジェクトを扱う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;
}
10

ここにいくつかのコードがあります:

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;
}
8
Khalid

get_object_vars($obj)はどうですか?オブジェクトのパブリックプロパティにのみアクセスしたい場合に便利です。 http://www.php.net/function.get-object-vars

6
Joe

オブジェクトを配列にキャストしてください。

$arr =  (array) $Obj;

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

5
Adeel

オブジェクトを配列に変換するには、明示的にキャストするだけです。

$name_of_array =  (array) $name_of_object;
5

こんにちは、

これは、PHPオブジェクトを連想配列に変換するための再帰的なPHP関数です。 

// --------------------------------------------------------- 
// ----- object_to_array_recusive --- 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_recusive ( $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_recusive($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_recusive($my_object); 
// -- or -- 
// $new_arr1 = object_to_array_recusive($my_object,TRUE); 
// -- or -- 
// $new_arr1 = object_to_array_recusive($my_object,1); 


// ---- return numeric array from object, ... use: 
$new_arr2 = object_to_array_recusive($my_object,FALSE); 
4
rabatto

オブジェクト配列を変換するためにPHPに関数を作成することもできます。

function object_to_array($object) {
    return (array) $object;
}
4
Rakhi Prajapati

あなたは簡単に結果を得るためにこの関数を使うことができます。

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

> = php5 を使用

4
Fiacre AYEDOUN

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に変換するもう1つのカスタム関数:

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
Bishoy

「よく知られている」コードのいくつかの改善

/*** 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
Gilbert BENABOU

データベースからオブジェクトとしてデータを取得するときにこれをしたいかもしれません - >

// 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;
}
3
metaldog
function readObject($object) {
    $name = get_class ($object);
    $name = str_replace('\\', "\\\\", $name); \\ Comment this line, if you dont 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;
}

特殊文字とクラス名なしで配列を返します

3
ovnia

まず第一に、あなたがオブジェクトから配列を必要とするなら、あなたはおそらく最初に配列としてデータを構成するべきです。それについて考えてください。 

ForeachステートメントやJSON変換を使わないでください。これを計画しているのであれば、やはりオブジェクトではなくデータ構造を使っています。

本当に必要な場合は、オブジェクト指向のアプローチを使用して、きれいでメインテーブル可能なコードを作成してください。例えば:

配列としてのオブジェクト

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

すべてのプロパティが必要な場合はtransferオブジェクトを使用してください

class PersonTransferObject
{
    private $person;

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

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

 }
3
John Smith

迷惑な星を変換および削除する:

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

おそらく、反射を使うよりも安くなるでしょう。

2
Fedir RYKHTIK

オブジェクトの動的アクセス属性に問題があるために多くの人がこのスレッドを見つけるので、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 .= " ";
        }

    }

}

Symfonyシリアライザコンポーネント を使うこともできます。 

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);
1
Andrey Nilov

@ SpYk3HHの簡単な解決策

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

    return $a;
}
1
Bsienn

この答えは、この記事のさまざまな答えをまとめたものですが、パブリックまたはプライベートのプロパティを持つ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;
}
1
Daniel Guerrero

あなたの場合は、「デコレータ」または「日付モデル変換」パターンを使用するのが正しかったです。例えば:

あなたのモデル

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

それでそれはより美しくそしてより正しいコードになるでしょう。

0
Daniel Abyan

オブジェクトから配列への変換ロジックを保存するためにトレイトを使用するのは良い考えだと思います。簡単な例

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());
0
Vitaly Pugach

ここでは 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**に置き換えられます。そうでなければ、無限ループのために失敗するでしょう。

0
Armin

私的な提案があります、あなたが個人的なメンバーでさえオブジェクトの中にオブジェクトを持っているならば:

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;
}
0
Karol Gasienica

型キャストを使用することで、あなたの問題を解決することができます。

$arrObj = array(yourReturnedObject);

次のようにして、新しいキーと値のペアを追加することもできます。

$arrObj['key'] = value;
0
Naveen Gupta
$Menu = new Admin_Model_DbTable_Menu(); 
$row = $Menu->fetchRow($Menu->select()->where('id = ?', $id));
$Addmenu = new Admin_Form_Addmenu(); 
$Addmenu->populate($row->toArray());