it-swarm.com.de

Konvertieren PHP Objekt zu assoziativem Array

Ich füge eine API in meine Website ein, die mit in Objekten gespeicherten Daten arbeitet, während mein Code mit Arrays geschrieben wird.

Ich möchte eine schnelle und schmutzige Funktion, um ein Objekt in ein Array zu konvertieren.

625
Haroldo

Schreibe es einfach

$array =  (array) $yourObject;

Von http://www.php.net/manual/de/language.types.array.php

Wenn ein Objekt in ein Array konvertiert wird, ist das Ergebnis ein Array, dessen Elemente die Eigenschaften des Objekts sind. Die Schlüssel sind die Namen der Mitgliedsvariablen, mit einigen wenigen Ausnahmen: Ganzzahl-Eigenschaften sind nicht zugänglich. Bei privaten Variablen wird der Klassenname dem Variablennamen vorangestellt. Geschützte Variablen haben ein '*' vor dem Variablennamen. Diese vorangestellten Werte haben auf beiden Seiten null Byte.

Beispiel: Einfaches Objekt

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

var_dump( (array) $object );

Ausgabe:

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

Beispiel: Komplexes Objekt

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

Ausgabe (wobei\0s zur besseren Verdeutlichung bearbeitet wurde):

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

Ausgabe mit var_export anstelle von var_dump:

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

Auf diese Weise werden bei der Konvertierung des Objektdiagramms keine tiefgreifenden Umwandlungen durchgeführt, und Sie müssen die Null-Bytes anwenden (wie im manuellen Zitat erläutert), um auf nicht öffentliche Attribute zuzugreifen. Dies funktioniert also am besten, wenn StdClass-Objekte oder Objekte mit nur öffentlichen Eigenschaften umgewandelt werden. Für schnell und schmutzig (was Sie verlangt haben) ist es in Ordnung.

Siehe auch diesen ausführlichen Blogbeitrag: 

1189
Gordon

Sie können tief verschachtelte Objekte schnell in assoziative Arrays konvertieren, indem Sie sich auf das Verhalten der JSON-Encoder/Decode-Funktionen verlassen:

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

Vom ersten Google-Treffer für "php object to assoc array" haben wir Folgendes:

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

Quelle bei codesnippets.joyent.com .

63
Maurycy

Wenn Ihre Objekteigenschaften öffentlich sind, können Sie Folgendes tun:

$array =  (array) $object;

Wenn sie privat oder geschützt sind, haben sie im Array merkwürdige Schlüsselnamen. In diesem Fall benötigen Sie also folgende Funktion:

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

Ausgabe

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

Alle anderen hier veröffentlichten Antworten funktionieren nur mit öffentlichen Attributen. Hier ist eine Lösung, die mit javabean - ähnlichen Objekten unter Verwendung von Reflexionen und Gettern arbeitet:

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

Hier ist ein Code:

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

Was ist mit get_object_vars($obj)? Scheint nützlich, wenn Sie nur auf die öffentlichen Eigenschaften eines Objekts zugreifen möchten . http://www.php.net/function.get-object-vars

6
Joe

Geben Sie Ihr Objekt in ein Array um.

$arr =  (array) $Obj;

Es wird Ihr Problem lösen.

5
Adeel

Um ein Objekt in ein Array zu konvertieren, konvertieren Sie es einfach explizit

$name_of_array =  (array) $name_of_object;
5

Hallo,

Hier ist meine rekursive PHP Funktion, um PHP Objekte in ein assoziatives Array zu konvertieren 

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


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

Anwendungsbeispiel:

// ---- 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

Sie können auch eine Funktion in PHP erstellen, um das Objektarray zu konvertieren.

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

Sie können diese Funktion problemlos verwenden, um ein Ergebnis zu erhalten.

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

verwenden Sie> = php5

4
Fiacre AYEDOUN

Benutzerdefinierte Funktion zum Konvertieren von stdClass in ein Array:

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

Eine weitere benutzerdefinierte Funktion zum Konvertieren von Array in 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;
    }
}

Verwendungsbeispiel:

    // 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

Möglicherweise möchten Sie dies tun, wenn Sie Daten als Objekte aus Datenbanken abrufen ->

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

gibt ein Array ohne Sonderzeichen und Klassennamen zurück

3
ovnia

Wenn Sie ein Array aus einem Objekt benötigen, sollten Sie die Daten wahrscheinlich zuerst als Array bilden. Denk darüber nach. 

Verwenden Sie keine foreach-Anweisungen oder JSON-Transformationen. Wenn Sie dies planen, arbeiten Sie wieder mit einer Datenstruktur, nicht mit einem Objekt.

Wenn Sie es wirklich benötigen, verwenden Sie den objektorientierten Ansatz, um einen sauberen und wartbaren Code zu erhalten. Zum Beispiel:

Objekt als Array

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

Wenn Sie alle Eigenschaften benötigen, verwenden Sie das Übertragungsobjekt

class PersonTransferObject
{
    private $person;

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

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

 }
3
John Smith

Störende Sterne konvertieren und entfernen:

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

Wahrscheinlich wird es günstiger als die Verwendung von Reflexionen.

2
Fedir RYKHTIK

Sie können auch Die Symfony Serializer-Komponente verwenden

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

Einige Verbesserungen des "bekannten" Codes

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

Wenn die Funktion Mitglied einer Klasse ist (wie oben), müssen Sie __FUNCTION__ in __METHOD__ ändern.

1
Gilbert BENABOU

Kurze Lösung von @ 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

Diese Antwort ist nur die Vereinigung der verschiedenen Antworten dieses Beitrags, aber es ist die Lösung, ein PHP Objekt mit öffentlichen oder privaten Eigenschaften mit einfachen Werten oder Arrays in assoziativen Arrays zu konvertieren.

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

Für Ihren Fall war es richtig/schön, wenn Sie die Muster "Dekorateur" oder "Datumsmodelltransformation" verwenden würden. Zum Beispiel:

Dein Modell

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

Dekorateur

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(),
        ];
    }
}

Verwendungszweck

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

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

So wird es schöner und korrekter Code sein.

0
Daniel Abyan

Ich denke, es ist eine gute Idee, Trait zu verwenden, um Objekt-zu-Array-Konvertierungslogik zu speichern. Einfaches Beispiel

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

Da viele Leute diesen Thread aufgrund von Problemen beim dynamischen Zugriff auf Attribute eines Objekts finden, möchte ich nur darauf hinweisen, dass Sie dies in php tun können: $valueRow->{"valueName"}

Im Kontext (HTML-Ausgabe zur besseren Lesbarkeit entfernt):

$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 .= " ";
        }

    }

}

Hier habe ich eine objectToArray () - Methode erstellt, die auch mit rekursiven Objekten funktioniert, beispielsweise wenn $objectA$objectB enthält, was wiederum auf $objectA verweist.

Außerdem habe ich die Ausgabe auf öffentliche Eigenschaften mit ReflectionClass beschränkt. Mach es los, wenn du es nicht brauchst.

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

Um bereits verwendete Objekte zu identifizieren, verwende ich in dieser (abstrakten) Klasse eine geschützte Eigenschaft namens $this->usedObjects. Wenn ein rekursives verschachteltes Objekt gefunden wird, wird es durch die Zeichenfolge **recursive** ersetzt. Sonst würde es wegen der Endlosschleife ausfallen.

0
Armin

Es gibt meinen Vorschlag, wenn Sie Objekte in Objekten mit sogar privaten Mitgliedern haben:

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

Durch die Verwendung der Typumwandlung können Sie Ihr Problem beheben. Fügen Sie Ihrem Rückkehrobjekt einfach folgende Zeilen hinzu:

$arrObj = array(yourReturnedObject);

sie können auch ein neues Schlüssel- und Wertepaar hinzufügen, indem Sie Folgendes verwenden:

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