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.
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:
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);
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 .
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;
}
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"
}
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;
}
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;
}
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
Geben Sie Ihr Objekt in ein Array um.
$arr = (array) $Obj;
Es wird Ihr Problem lösen.
Um ein Objekt in ein Array zu konvertieren, konvertieren Sie es einfach explizit
$name_of_array = (array) $name_of_object;
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);
Sie können auch eine Funktion in PHP erstellen, um das Objektarray zu konvertieren.
function object_to_array($object) {
return (array) $object;
}
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
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);
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;
}
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
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();
];
}
}
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.
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);
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.
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;
}
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;
}
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.
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());
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.
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;
}
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;
$Menu = new Admin_Model_DbTable_Menu();
$row = $Menu->fetchRow($Menu->select()->where('id = ?', $id));
$Addmenu = new Admin_Form_Addmenu();
$Addmenu->populate($row->toArray());