Antworten:
Tippe es einfach
$array = (array) $yourObject;
Von Arrays :
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 bemerkenswerten Ausnahmen: Auf Integer-Eigenschaften kann nicht zugegriffen werden. Bei privaten Variablen wird dem Klassennamen der Klassenname vorangestellt. Geschützte Variablen haben ein '*' vor dem Variablennamen. Diese vorangestellten Werte haben auf beiden Seiten Null-Bytes.
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 (aus Gründen der Übersichtlichkeit mit \ 0s bearbeitet):
array(3) {
'\0Foo\0foo' => int(1)
'\0*\0bar' => int(2)
'baz' => class stdClass#2 (0) {}
}
Ausgabe mit var_export
statt var_dump
:
array (
'' . "\0" . 'Foo' . "\0" . 'foo' => 1,
'' . "\0" . '*' . "\0" . 'bar' => 2,
'baz' =>
stdClass::__set_state(array(
)),
)
Wenn Sie auf diese Weise typisieren, wird das Objektdiagramm nicht tiefgreifend umgewandelt, und Sie müssen die Nullbytes (wie im manuellen Anführungszeichen erläutert) anwenden, 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 gefragt haben) ist es in Ordnung.
Siehe auch diesen ausführlichen Blog-Beitrag:
[1 => "one"]
wird["1" => "one"]
(array)
und (object)
funktioniert zuverlässig und gleich in allen Versionen seit PHP 4.3. Siehe 3v4l.org/X6lhm . Wenn Sie einen Syntaxfehler erhalten, haben Sie etwas falsch gemacht.
empty
. Sie können keinen Ausdruck mit empty
vor 5.5 verwenden. Dies hat nichts mit Typografie zu tun;)
Sie können tief verschachtelte Objekte schnell in assoziative Arrays konvertieren, indem Sie sich auf das Verhalten der JSON-Codierungs- / Decodierungsfunktionen verlassen:
$array = json_decode(json_encode($nested_object), true);
Ab dem ersten Google-Treffer für " PHP-Objekt zu 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;
}
Die Quelle ist auf Codesnippets.joyent.com .
function objectToArray($o) { $a = array(); foreach ($o as $k => $v) $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v; return $a; }
Dies setzt nur alles, was kein Objekt oder Array ist, und fährt ohne wiederholten Rückruf der Methode fort, sofern dies nicht erforderlich ist.
Wenn Ihre Objekteigenschaften öffentlich sind, können Sie Folgendes tun:
$array = (array) $object;
Wenn sie privat oder geschützt sind, haben sie seltsame Schlüsselnamen im Array. In diesem Fall benötigen Sie also die 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"
}
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;
}
Alle anderen hier veröffentlichten Antworten funktionieren nur mit öffentlichen Attributen. Hier ist eine Lösung, die mit JavaBeans- ähnlichen Objekten unter Verwendung von Reflektion und Gettern funktioniert :
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;
}
public
Eigenschaften?
Was ist mit get_object_vars($obj)
? Es erscheint nützlich, wenn Sie nur auf die öffentlichen Eigenschaften eines Objekts zugreifen möchten.
Siehe get_object_vars .
Wenn Sie ein Array von einem Objekt benötigen, sollten Sie die Daten wahrscheinlich zuerst als Array zusammenstellen. Denk darüber nach.
Verwenden Sie keine foreach
Anweisung oder JSON-Transformationen. Wenn Sie dies planen, arbeiten Sie wieder mit einer Datenstruktur, nicht mit einem Objekt.
Wenn Sie es wirklich brauchen, verwenden Sie einen objektorientierten Ansatz, um einen sauberen und wartbaren Code zu haben. 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 ein Übertragungsobjekt:
class PersonTransferObject
{
private $person;
public function __construct(Person $person) {
$this->person = $person;
}
public function toArray() {
return [
// 'name' => $this->person->getName();
];
}
}
Mit dieser Funktion können Sie ganz einfach das Ergebnis 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 PHP 5 oder höher.
Hier ist meine rekursive PHP-Funktion zum Konvertieren von PHP-Objekten in ein assoziatives Array:
// ---------------------------------------------------------
// ----- 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;
}
// ---------------------------------------------------------
// ---------------------------------------------------------
Anwendungsbeispiel:
// ---- 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);
$new_arr1 = (array) $my_object;
Um ein Objekt in ein Array zu konvertieren, wandeln Sie es einfach explizit um:
$name_of_array = (array) $name_of_object;
Sie können auch eine Funktion in PHP erstellen, um ein Objektarray zu konvertieren:
function object_to_array($object) {
return (array) $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;
}
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 Arrays 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;
}
}
Anwendungsbeispiel:
// 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);
Verwenden:
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;
}
Es gibt ein Array ohne Sonderzeichen und Klassennamen zurück.
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 ein assoziatives Array 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;
}
Einige Verbesserungen am "bekannten" Code
/*** 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
Beachten Sie, dass , wenn die Funktion Mitglied einer Klasse ist (wie oben) Sie ändern müssen , __FUNCTION__
um__METHOD__
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);
Für Ihren Fall war es richtig / schön, wenn Sie die Muster "Dekorator" 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();
Es wird also schöner und korrekter Code.
Lästige Sterne umwandeln und entfernen:
$array = (array) $object;
foreach($array as $key => $val)
{
$new_array[str_replace('*_', '', $key)] = $val;
}
Wahrscheinlich ist es billiger als die Verwendung von Reflexionen.
Da viele Leute diese Frage finden, weil sie Probleme mit dem dynamischen Zugriff auf Attribute eines Objekts haben, 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 .= " ";
}
}
}
Mit Typecasting können Sie Ihr Problem lösen. Fügen Sie Ihrem Rückgabeobjekt einfach die folgenden Zeilen hinzu:
$arrObj = array(yourReturnedObject);
Sie können ihm auch ein neues Schlüssel- und Wertepaar hinzufügen, indem Sie Folgendes verwenden:
$arrObj['key'] = value;
Ich denke, es ist eine gute Idee, Merkmale zu verwenden, um die Konvertierungslogik von Objekt zu Array zu speichern. Ein 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());
$Menu = new Admin_Model_DbTable_Menu();
$row = $Menu->fetchRow($Menu->select()->where('id = ?', $id));
$Addmenu = new Admin_Form_Addmenu();
$Addmenu->populate($row->toArray());
Hier habe ich eine objectToArray () -Methode erstellt, die auch mit rekursiven Objekten funktioniert, z. B. wenn $objectA
enthält, auf $objectB
welche Punkte erneut verwiesen wird$objectA
.
Außerdem habe ich die Ausgabe mit ReflectionClass auf öffentliche Eigenschaften beschränkt. Werde 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 eine geschützte Eigenschaft in dieser (abstrakten) Klasse mit dem Namen $this->usedObjects
. Wenn ein rekursiv verschachteltes Objekt gefunden wird, wird es durch die Zeichenfolge ersetzt **recursive**
. Andernfalls würde es wegen der Endlosschleife fehlschlagen.
$usedObjects
wird zu Beginn nicht initialisiert, daher führt ein mehrmaliger Aufruf zu falschen Ergebnissen bei späteren Aufrufen. Außerdem geben Sie es am Ende nicht frei, sodass Ihre Objekte niemals aus dem Speicher entfernt werden.
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;
}
Ich benutze dies (benötigte rekursive Lösung mit richtigen Schlüsseln):
/**
* 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;
}
Anwendungsbeispiel, folgender Code:
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)
Wird dies drucken:
array(2) {
["bb"] => array(1) {
["two"] => int(22)
}
["one"] => int(11)
}
ArrayAccess
Schnittstelle, möglicherweise in Kombination mit dieser Lösung. php.net/manual/en/class.arrayaccess.php