एक PHP ऑब्जेक्ट को एक सहयोगी सरणी में परिवर्तित करें


760

मैं अपनी वेबसाइट पर एक एपीआई को एकीकृत कर रहा हूं जो वस्तुओं में संग्रहीत डेटा के साथ काम करता है जबकि मेरा कोड सरणियों का उपयोग करके लिखा जाता है।

किसी ऑब्जेक्ट को किसी अरै में बदलने के लिए मैं क्विक-एंड-डर्टी फंक्शन पसंद करता हूं।

जवाबों:


1392

बस इसे टाइपकास्ट करें

$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 ऑब्जेक्ट्स या ऑब्जेक्ट्स को केवल पब्लिक प्रॉपर्टीज़ के साथ कास्ट करें। त्वरित और गंदे के लिए (आपने जो मांगा था) वह ठीक है।

इसे भी गहराई से ब्लॉग पोस्ट में देखें:


3
ArrayAccessइंटरफ़ेस पर भी विचार करें, शायद इस समाधान के साथ संयोजन में। php.net/manual/en/class.arrayaccess.php
alttag

3
आपके पास पूर्णांक कुंजियाँ हैं, उन्हें स्ट्रिंग में परिवर्तित किया जाएगा और यह बड़ा मुद्दा बन सकता है। जैसे [1 => "one"]बन जाता है["1" => "one"]
ओलेग

2
साथ @Howie Typecasting (array)और (object)मज़बूती से काम करता है और पीएचपी 4.3 के बाद से सभी संस्करणों में एक ही। 3v4l.org/X6lhm देखें । यदि आपको सिंटैक्स त्रुटि मिलती है, तो आपने कुछ गलत किया।
गॉर्डन

2
@ हाईवे के लिए चैंज खंडempty देखें । आप empty5.5 से पहले की अभिव्यक्ति का उपयोग नहीं कर सकते । यह टाइपकास्टिंग के लिए पूरी तरह से असंबंधित है;)
गॉर्डन

4
Typecast। हाँ। टाइप करें Freakin CAST! अच्छा। +1
कौशिक मकवाना

345

आप JSON एनकोड / डिकोड फ़ंक्शन के व्यवहार पर भरोसा करके गहरी नेस्टेड वस्तुओं को जल्दी से साहचर्य सरणियों में बदल सकते हैं:

$array = json_decode(json_encode($nested_object), true);

12
यदि आप एक पूर्ण गहराई पुनरावर्ती रूपांतरण चाहते हैं (और निश्चित रूप से बुरा प्रदर्शन बुरा नहीं है) तो यह सबसे अच्छा उपाय है
जूलियन हबेकॉस्ट

2
यह सिर्फ मेरी स्थिति के साथ पूरी तरह से मेरी मदद करता है, बहुत बहुत धन्यवाद।
सीजर बिलिच

9
सम्मान से, मुझे लगता है कि यह अभी भी काम करता है ... सच करने के लिए 2 पैरामीटर सेट करने के लिए मत भूलना।
कर्क B

3
दूसरे पैरामीटर ने समस्या को हल किया, PHP 5.6.25 के लिए काम कर रहा है। धन्यवाद!
जू ओलिवेरा

3
नेस्टेड वस्तुओं के लिए एकदम सही काम करता है! धन्यवाद!
मेलोडी

68

" 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 पर है


16
व्यक्तिगत रूप से, मुझे हर मूल्य के लिए फ़ंक्शन को याद करने का विचार पसंद नहीं है। मेरे पास एक समान संस्करण है, लेकिन 3 पंक्तियों में: function objectToArray($o) { $a = array(); foreach ($o as $k => $v) $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v; return $a; }यह बस कुछ भी सेट करता है जो एक वस्तु या सरणी नहीं है और जब तक आवश्यक नहीं है, तब तक दोहराए जाने वाले याद के बिना जारी रहता है।
SpYk3HH

13
@ SpYk3HH: अपना जवाब लिखें?
डैनमैन

2
"Php ऑब्जेक्ट टू एशोक एरे" के लिए पहली हिट है, stackoverflow.com/questions/4345554/…
क्रिस

यह (@ SpYk3HH से संस्करण) json_encode विकल्प ( stackoverflow.com/a/16111687/470749 ) की तुलना में मेरे लिए भी धीमी गति से प्रदर्शन करता है । मुझे नहीं पता कि ये दृष्टिकोण कभी बेहतर क्यों होंगे।
रयान

1
@ रियान जोंस एनकोड और डिकोड नाव के साथ काम नहीं करेगा और फ्लोट के लिए INFINITE मान और संभावित रूप से अन्य मुद्दे हो सकते हैं जो मैं अपने सिर के ऊपर से नहीं सोच सकता, लेकिन कई मामलों में यह एक बेहतर विकल्प हो सकता है। अनुकूलन के लिए के रूप में, यह क्या जरूरत संदर्भ है - मुझे एक पोस्ट मैं इस विषय पर लिखा था प्लग जाने evidentlycube.com/blog/game-optimization/when-to-optimize । टीएल; ड्र; जा रहा है, उन चीजों का अनुकूलन न करें जो चल रहे समय का बहुत बड़ा हिस्सा नहीं लेते हैं क्योंकि पूरे आवेदन के संदर्भ में लाभ अर्थहीन हैं।
मॉरिशी

61

यदि आपकी वस्तुएं सार्वजनिक हैं, तो आप कर सकते हैं:

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

यदि आपकी संपत्ति सुरक्षित है, तो असफल (झूठी) संरक्षित दृश्यता में वापस बदल जाएगी? या यह इसे निजी बना देगा?
निक मिशेल

एकमात्र समाधान जो मैंने पाया, वह संरक्षित गुणों के साथ काम किया। धन्यवाद
dav

3
निजी और संरक्षित चर के लिए सबसे अच्छा समाधान !!
HIRA THAKUR

यहाँ लाइन $ प्रॉपर्टी-> सेटएबल (झूठी); हर संपत्ति पर अमल किया जाएगा - भले ही वह सार्वजनिक था ...
फ्रेंकोइस बुर्जुआ

बहुत बढ़िया ... कमाल है ... बहुत बढ़िया। धन्यवाद।
फरीद अब्बास

14
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"
}

1
इस समाधान के समर्थक और विपक्ष? कक्षा टेस्ट {const A = 1 के रूप में घोषित एक वर्ग के बारे में क्या; सार्वजनिक $ जनक = नया परीक्षण (); }
मट्टेओ गगिनजियो

13

यहाँ कुछ कोड है:

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

मेरे लिए सबसे अच्छा काम करता है (लेकिन मुझे 'xxx' को हटाने और $ डेटा वापस करने की आवश्यकता है)
गेरफ्रीड

12

यहां पोस्ट किए गए अन्य सभी उत्तर केवल सार्वजनिक विशेषताओं के साथ काम कर रहे हैं। यहाँ एक समाधान है जो प्रतिबिंब और गेटर्स का उपयोग करते हुए 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गुणों के अलावा और कुछ भी क्यों चाहिए ?
SpYk3HH

@ SpYk3HH: मैंने सवाल नहीं पूछा। मैं यह भी नहीं जानता कि किसी को पहली जगह में किसी वस्तु पर एक सरणी क्यों पसंद होगी।
फ्रेंकोइस बुर्जुआ

एह, मैं अक्सर क्वेरी परिणामों को केवल एक समान "सूची" प्रदान करने के लिए सरणी में परिवर्तित करना पसंद करता हूं, क्योंकि ऐप में सबसे दूसरी चीज "लूपेड" होनी चाहिए जो एरेज़ होती है। बस "सार्वभौमिक लूप विधियों" को लिखना आसान बनाता है। अक्सर, अगर मैं किसी ऑब्जेक्ट का उपयोग कर रहा हूं, तो मैं इसके गुणों के माध्यम से लूपिंग नहीं कर रहा हूं, मैं इसे एक ऑब्जेक्ट के रूप में उपयोग कर रहा हूं और आवश्यकतानुसार उन गुणों का उपयोग कर रहा हूं।
SpYk3HH

11

किस बारे में get_object_vars($obj)? यह उपयोगी लगता है यदि आप केवल किसी वस्तु के सार्वजनिक गुणों को एक्सेस करना चाहते हैं।

Get_object_vars देखें ।


10

अपनी ऑब्जेक्ट को किसी सरणी में टाइप करें।

$arr =  (array) $Obj;

यह आपकी समस्या का समाधान करेगा।


5
यदि आपके पास निजी या संरक्षित गुण हैं, तो यह नहीं होगा।
forsberg

2
सबसे सरल उपाय। धन्यवाद
एएसडी

6

सबसे पहले, यदि आपको किसी ऑब्जेक्ट से एक सरणी की आवश्यकता है, तो आपको संभवतः पहले एक सरणी के रूप में डेटा का गठन करना चाहिए। इसके बारे में सोचो।

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

 }

6

परिणाम प्राप्त करने के लिए आप आसानी से इस फ़ंक्शन का उपयोग कर सकते हैं:

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 या बाद का उपयोग करें ।


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

3
.. या ऑनलाइनर:$new_arr1 = (array) $my_object;
फूबर

1
ऑन्लाइनर संस्करण उथला है, इसलिए समतुल्य नहीं है।
जोनाथन लिडबेक


5

आप ऑब्जेक्ट सरणी बदलने के लिए PHP में एक फ़ंक्शन भी बना सकते हैं:

function object_to_array($object) {
    return (array) $object;
}

@ अचिंतंडे-रोतिमी, मैंने एक सामान्य कार्य बनाया है और दिखाया है।
राखी प्रजापति

4

डेटाबेस से ऑब्जेक्ट के रूप में डेटा प्राप्त करने पर आप ऐसा करना चाह सकते हैं:

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

2
41 उत्थान के साथ एक स्वीकृत उत्तर है, 1 या 10 नहीं, 41. आपका उत्तर इसमें क्या जोड़ता है?
यारोस्लाव

4

कस्टम फ़ंक्शन को एक सरणी में 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);

4

उपयोग:

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

यह विशेष वर्ण और वर्ग नाम के बिना एक सरणी देता है।


4

यह उत्तर केवल इस पोस्ट के विभिन्न उत्तरों का संघ है, लेकिन यह एक 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;
}

3

"अच्छी तरह से 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__



3

आपके मामले के लिए यह सही / सुंदर था यदि आप "डेकोरेटर" या "तिथि मॉडल परिवर्तन" पैटर्न का उपयोग करेंगे। उदाहरण के लिए:

आपका मॉडल

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

तो यह अधिक सुंदर और अधिक सही कोड होगा।


3

कष्टप्रद तारों को बदलना और हटाना:

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

संभवतः, यह प्रतिबिंबों का उपयोग करने की तुलना में सस्ता होगा।


2

@ SpYk3HH का संक्षिप्त समाधान

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

    return $a;
}

2

चूंकि बहुत से लोग इस प्रश्न को किसी वस्तु की गतिशील रूप से एक्सेस विशेषताओं से परेशान होने के कारण पाते हैं, इसलिए मैं सिर्फ यह बताऊंगा कि आप इसे 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 .= " ";
        }
    }
}

2

टाइपकास्टिंग का उपयोग करके आप अपनी समस्या को हल कर सकते हैं। बस अपनी वापसी वस्तु में निम्नलिखित पंक्तियाँ जोड़ें:

$arrObj = array(yourReturnedObject);

आप इसका उपयोग करके एक नई कुंजी और मूल्य जोड़ी भी जोड़ सकते हैं:

$arrObj['key'] = value;

2

मुझे लगता है कि ऑब्जेक्ट-टू-ऐरे कन्वर्ज़िंग लॉजिक को स्टोर करने के लिए ट्रेट्स का उपयोग करना एक अच्छा विचार है। एक सरल उदाहरण:

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

1
$Menu = new Admin_Model_DbTable_Menu(); 
$row = $Menu->fetchRow($Menu->select()->where('id = ?', $id));
$Addmenu = new Admin_Form_Addmenu(); 
$Addmenu->populate($row->toArray());

मैं मान रहा हूं कि यह उत्तर एक सिद्धांत (या समान) रिकॉर्ड के लिए है।
nikoskip 18

1

यहाँ मैंने एक 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प्रारंभ में आरंभिक नहीं है, इसलिए कई बार कॉल करने पर बाद के कॉल में गलत परिणाम मिलेंगे। इसके अलावा, आप इसे अंत में मुक्त नहीं करते हैं, इसलिए आपकी वस्तुओं को स्मृति से कभी भी हटाया नहीं जाएगा।
हैप्पीडॉग

1

मेरा प्रस्ताव है, अगर आपके पास निजी सदस्यों के साथ वस्तुओं में भी हैं:

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

1

मैं इसका उपयोग करता हूं (उचित कुंजियों के साथ पुनरावर्ती समाधान की आवश्यकता है):

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

वस्तुओं की सरणी के साथ वस्तुओं का समर्थन करने के लिए हम आपके फ़ंक्शन को कैसे उन्नत कर सकते हैं?
celsowm
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.