जवाबों:
बस इसे टाइपकास्ट करें
$array = (array) $yourObject;
से सरणी :
यदि किसी वस्तु को एक सरणी में परिवर्तित किया जाता है, तो परिणाम एक सरणी है जिसके तत्व ऑब्जेक्ट के गुण हैं। चाबियाँ कुछ उल्लेखनीय अपवादों के साथ सदस्य चर नाम हैं: पूर्णांक गुण अस्वीकार्य हैं; निजी चर का नाम चर नाम से पहले वर्ग का नाम होता है; संरक्षित चर में चर नाम के लिए एक '*' है। इन प्रीपेंड किए गए मानों में दोनों तरफ नल बाइट्स हैं।
उदाहरण: साधारण वस्तु
$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 );
आउटपुट (स्पष्टता के लिए संपादित किए गए \ 0s के साथ):
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(
)),
)
इस तरह टाइपकास्ट करने से ऑब्जेक्ट ग्राफ की गहरी ढलाई नहीं होगी और आपको किसी भी गैर-सार्वजनिक विशेषताओं तक पहुंचने के लिए नल बाइट्स (जैसा कि मैनुअल उद्धरण में समझाया गया है) को लागू करने की आवश्यकता है। इसलिए यह सबसे अच्छा काम करता है जब StdClass ऑब्जेक्ट्स या ऑब्जेक्ट्स को केवल पब्लिक प्रॉपर्टीज़ के साथ कास्ट करें। त्वरित और गंदे के लिए (आपने जो मांगा था) वह ठीक है।
इसे भी गहराई से ब्लॉग पोस्ट में देखें:
[1 => "one"]
बन जाता है["1" => "one"]
(array)
और (object)
मज़बूती से काम करता है और पीएचपी 4.3 के बाद से सभी संस्करणों में एक ही। 3v4l.org/X6lhm देखें । यदि आपको सिंटैक्स त्रुटि मिलती है, तो आपने कुछ गलत किया।
empty
देखें । आप empty
5.5 से पहले की अभिव्यक्ति का उपयोग नहीं कर सकते । यह टाइपकास्टिंग के लिए पूरी तरह से असंबंधित है;)
आप JSON एनकोड / डिकोड फ़ंक्शन के व्यवहार पर भरोसा करके गहरी नेस्टेड वस्तुओं को जल्दी से साहचर्य सरणियों में बदल सकते हैं:
$array = json_decode(json_encode($nested_object), true);
" 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;
}
स्रोत codenippets.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; }
यह बस कुछ भी सेट करता है जो एक वस्तु या सरणी नहीं है और जब तक आवश्यक नहीं है, तब तक दोहराए जाने वाले याद के बिना जारी रहता है।
यदि आपकी वस्तुएं सार्वजनिक हैं, तो आप कर सकते हैं:
$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;
}
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"
}
यहाँ कुछ कोड है:
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;
}
यहां पोस्ट किए गए अन्य सभी उत्तर केवल सार्वजनिक विशेषताओं के साथ काम कर रहे हैं। यहाँ एक समाधान है जो प्रतिबिंब और गेटर्स का उपयोग करते हुए JavaBeans जैसी वस्तुओं के साथ काम करता है :
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
गुणों के अलावा और कुछ भी क्यों चाहिए ?
किस बारे में get_object_vars($obj)
? यह उपयोगी लगता है यदि आप केवल किसी वस्तु के सार्वजनिक गुणों को एक्सेस करना चाहते हैं।
Get_object_vars देखें ।
सबसे पहले, यदि आपको किसी ऑब्जेक्ट से एक सरणी की आवश्यकता है, तो आपको संभवतः पहले एक सरणी के रूप में डेटा का गठन करना चाहिए। इसके बारे में सोचो।
एक 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();
];
}
}
परिणाम प्राप्त करने के लिए आप आसानी से इस फ़ंक्शन का उपयोग कर सकते हैं:
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;
}
PHP 5 या बाद का उपयोग करें ।
PHP ऑब्जेक्ट्स को एक सहयोगी सरणी में बदलने के लिए मेरा पुनरावर्ती PHP फ़ंक्शन है:
// ---------------------------------------------------------
// ----- 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;
}
// ---------------------------------------------------------
// ---------------------------------------------------------
उपयोग उदाहरण:
// ---- 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;
किसी ऑब्जेक्ट को सरणी में बदलने के लिए बस इसे स्पष्ट रूप से डालें:
$name_of_array = (array) $name_of_object;
आप ऑब्जेक्ट सरणी बदलने के लिए PHP में एक फ़ंक्शन भी बना सकते हैं:
function object_to_array($object) {
return (array) $object;
}
डेटाबेस से ऑब्जेक्ट के रूप में डेटा प्राप्त करने पर आप ऐसा करना चाह सकते हैं:
// 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;
}
कस्टम फ़ंक्शन को एक सरणी में 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 में बदलने के लिए एक और कस्टम फ़ंक्शन:
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);
उपयोग:
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;
}
यह विशेष वर्ण और वर्ग नाम के बिना एक सरणी देता है।
यह उत्तर केवल इस पोस्ट के विभिन्न उत्तरों का संघ है, लेकिन यह एक 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;
}
"अच्छी तरह से knwon" कोड के लिए कुछ impovements
/*** 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__
इसके अलावा, आप सिम्फनी Serializer घटक का उपयोग कर सकते हैं
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);
आपके मामले के लिए यह सही / सुंदर था यदि आप "डेकोरेटर" या "तिथि मॉडल परिवर्तन" पैटर्न का उपयोग करेंगे। उदाहरण के लिए:
आपका मॉडल
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();
तो यह अधिक सुंदर और अधिक सही कोड होगा।
कष्टप्रद तारों को बदलना और हटाना:
$array = (array) $object;
foreach($array as $key => $val)
{
$new_array[str_replace('*_', '', $key)] = $val;
}
संभवतः, यह प्रतिबिंबों का उपयोग करने की तुलना में सस्ता होगा।
चूंकि बहुत से लोग इस प्रश्न को किसी वस्तु की गतिशील रूप से एक्सेस विशेषताओं से परेशान होने के कारण पाते हैं, इसलिए मैं सिर्फ यह बताऊंगा कि आप इसे 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 .= " ";
}
}
}
टाइपकास्टिंग का उपयोग करके आप अपनी समस्या को हल कर सकते हैं। बस अपनी वापसी वस्तु में निम्नलिखित पंक्तियाँ जोड़ें:
$arrObj = array(yourReturnedObject);
आप इसका उपयोग करके एक नई कुंजी और मूल्य जोड़ी भी जोड़ सकते हैं:
$arrObj['key'] = value;
मुझे लगता है कि ऑब्जेक्ट-टू-ऐरे कन्वर्ज़िंग लॉजिक को स्टोर करने के लिए ट्रेट्स का उपयोग करना एक अच्छा विचार है। एक सरल उदाहरण:
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());
यहाँ मैंने एक 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**
। अन्यथा अनंत पाश के कारण यह विफल हो जाता।
$usedObjects
प्रारंभ में आरंभिक नहीं है, इसलिए कई बार कॉल करने पर बाद के कॉल में गलत परिणाम मिलेंगे। इसके अलावा, आप इसे अंत में मुक्त नहीं करते हैं, इसलिए आपकी वस्तुओं को स्मृति से कभी भी हटाया नहीं जाएगा।
मेरा प्रस्ताव है, अगर आपके पास निजी सदस्यों के साथ वस्तुओं में भी हैं:
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;
}
मैं इसका उपयोग करता हूं (उचित कुंजियों के साथ पुनरावर्ती समाधान की आवश्यकता है):
/**
* 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;
}
उपयोग का उदाहरण, निम्नलिखित कोड:
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)
इसे प्रिंट करेंगे:
array(2) {
["bb"] => array(1) {
["two"] => int(22)
}
["one"] => int(11)
}
ArrayAccess
इंटरफ़ेस पर भी विचार करें, शायद इस समाधान के साथ संयोजन में। php.net/manual/en/class.arrayaccess.php