PHP nesnesini ilişkilendirilebilir bir diziye dönüştürme


760

Kodumu diziler kullanılarak yazılırken nesnelerde depolanan verilerle çalışan web siteme bir API entegre ediyorum.

Bir nesneyi bir diziye dönüştürmek için hızlı ve kirli bir işlev istiyorum.

Yanıtlar:


1392

Sadece yazın

$array = (array) $yourObject;

Gönderen Diziler :

Bir nesne bir diziye dönüştürülürse, sonuç öğeleri nesnenin özellikleri olan bir dizidir. Anahtarlar, birkaç önemli istisna dışında üye değişken adlarıdır: tamsayı özelliklerine erişilemez; özel değişkenler sınıf adının yerine değişken adını ekler; korumalı değişkenlerin başında değişken adı '*' vardır. Bu tercih edilen değerlerin her iki tarafında da boş bayt vardır.

Örnek: Basit Nesne

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

var_dump( (array) $object );

Çıktı:

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

Örnek: Karmaşık Nesne

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

Çıktı (netlik için \ 0s düzenlenmiş olarak):

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

Şunun var_exportyerine ile çıktı var_dump:

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

Bu şekilde belirtmek nesne grafiğinin derin dökümünü yapmaz ve herkese açık olmayan özelliklere erişmek için boş baytları (manuel alıntıda açıklandığı gibi) uygulamanız gerekir. Bu, StdClass nesnelerini veya yalnızca ortak özelliklere sahip nesneleri yayınlarken en iyi sonucu verir. Hızlı ve kirli (ne istediğini) için iyi.

Ayrıca bu ayrıntılı blog yayınına bakın:


3
Ayrıca ArrayAccess, belki de bu çözümle birlikte arayüzü de düşünün . php.net/manual/tr/class.arrayaccess.php
alttag

3
Dize dönüştürülecek tamsayı anahtarları var ve bu büyük soruna neden olabilir. Eg [1 => "one"]olur["1" => "one"]
Oleg

2
@Howie ile tiplemeleri (array)ve (object)güvenilir şekilde çalışır ve PHP 4.3 beri tüm sürümleri arasında aynı. Bkz. 3v4l.org/X6lhm . Bir sözdizimi hatası alırsanız, yanlış bir şey yaptınız.
Gordon

2
@ İçin Changelog bölümüne bakınempty . empty5.5'ten önceki bir ifadeyi kullanamazsınız . Bu, daktilo ile tamamen ilgisiz;)
Gordon

4
Typecast. Evet. Freakin CAST yazın! İyi. +1
Kaushik Makwana

346

JSON kodlama / kod çözme işlevlerinin davranışına güvenerek, derinden iç içe geçmiş nesneleri ilişkilendirilebilir dizilere hızlı bir şekilde dönüştürebilirsiniz:

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

12
Tam bir derinlik yinelemeli dönüşüm istiyorsanız (ve elbette kötü performansa
aldırmayın

2
Bu durumumda bana tamamen yardımcı oldu, çok teşekkürler.
Cesar Bielich

9
Saygılarımla, hala işe yarıyor ... 2. parametreyi true olarak ayarlamayı unutmayın.
Kirk B

3
İkinci parametre PHP 5.6.25 için çalışarak sorunu çözdü. Teşekkürler!
Ju Oliveira

3
İç içe nesneler için mükemmel çalışır! Teşekkürler!
Melody

68

" PHP nesnesi için dizi dizisi " için ilk Google hit itibaren biz var:

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

Kaynak codesnippets.joyent.com adresinde .


16
Şahsen, her değer için işlevi hatırlama fikrinden hoşlanmıyorum. Ben benzer bir sürümü var, ama 3 satır: function objectToArray($o) { $a = array(); foreach ($o as $k => $v) $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v; return $a; }Bu sadece bir nesne veya dizi olmayan bir şey ayarlar ve gerekmedikçe yöntemi tekrarlayan hatırlama olmadan devam ediyor.
SpYk3HH

13
@ SpYk3HH: Kendi cevabınızı mı yazdınız?
DanMan

2
"Php nesnesi assoc dizisi" için ilk hit stackoverflow.com/questions/4345554/…
Chris

Bu (ve @ SpYk3HH sürümü) benim için json_encode seçeneğinden ( stackoverflow.com/a/16111687/470749 ) daha yavaş çalışıyor gibi görünüyor . Bu yaklaşımların neden daha çok tercih edileceğini bilmiyorum.
Ryan

1
@Ryan json kodlama ve kod çözme şamandıra için NaN ve INFINITE değerleri ile çalışmaz ve potansiyel olarak kafamın üstünden düşünemediğim başka sorunları olabilir ama birçok durumda daha iyi bir seçenek olabilir. Optimizasyon gelince, ihtiyacı olan bağlamdır - bu konu hakkında yazdığım bir gönderiyi evidentlycube.com/blog/game-optimization/when-to-optimize . tl; dr, çalışma süresinin büyük kısmını almayan şeyleri optimize etmeyin, çünkü faydalar tüm uygulama bağlamında anlamsızdır.
Maurycy

61

Nesne özellikleriniz herkese açıksa şunları yapabilirsiniz:

$array =  (array) $object;

Özel veya korunmuşlarsa, dizide tuhaf anahtar adları olacaktır. Yani, bu durumda aşağıdaki fonksiyona ihtiyacınız olacak:

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

Mülkünüz korunuyorsa, setAccessible (false) özelliği korumalı görünürlük durumuna geri döndürür mü? yoksa özel mi yapacak?
Nick Mitchell

Bulduğum tek çözüm, korumalı özelliklerle çalıştı. Teşekkürler
dav

3
özel ve korumalı değişkenler için en iyi çözüm !!
HIRA THAKUR

Burada $ property-> setAccessible (false); kamuya açık olsa bile her mülke idam edilecek ...
Francois Bourgeois

Mükemmel ... Harika ... Harika. Teşekkürler.
Farid Abbas

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

Çıktı

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

1
Bu çözümün yanlısı ve eksileri? Sınıf Testi olarak bildirilen bir sınıfa {const A = 1; public $ parent = new Test (); }
Matteo Gaggiano

13

İşte bazı kod:

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

benim için en iyi çalışır (ancak '
xxx'i

12

Burada gönderilen diğer tüm yanıtlar yalnızca genel özelliklerle çalışmaktadır. Yansıma ve alıcıları kullanarak JavaBeans benzeri nesnelerle çalışan bir çözüm :

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

Evet, ama ... Eğer Object / Array değişkenini bir değişken olarak kullanıyorsanız, tüm bunlar da neden olur, neden publicözelliklerden başka bir şeye ihtiyacınız var ?
SpYk3HH

@ SpYk3HH: Soruyu sormadım. Neden kimse ilk etapta bir nesne üzerinde bir dizi tercih ediyorum bilmiyorum.
Francois Bourgeois

Eh, sık sık bir döngü içinde olması gereken bir uygulamada "döngü" olması gereken bir diğer şey diziler olma eğiliminde olduğu gibi, sadece döngü için tek tip bir "liste" sağlamak için sorgu sonuçlarını diziye dönüştürmeyi tercih ederim. Sadece "evrensel döngü yöntemleri" yazmayı kolaylaştırır. Genellikle, bir nesneyi kullanıyorsam, onun özellikleri arasında döngü yapmıyorum, bir nesne olarak kullanıyorum ve bu özellikleri gerektiği gibi kullanıyorum.
SpYk3HH

11

Ne olmuş get_object_vars($obj)? Yalnızca bir nesnenin genel özelliklerine erişmek istiyorsanız yararlı görünüyor.

Bkz. Get_object_vars .


10

Nesnenizi bir diziye yayınla yazın.

$arr =  (array) $Obj;

Sorununuzu çözecek.


5
Hayır, özel veya korumalı mülkleriniz varsa olmaz.
forsberg

2
En basit çözüm. Teşekkürler
ASD

6

Her şeyden önce, bir nesneden bir diziye ihtiyacınız varsa, muhtemelen ilk önce verileri bir dizi olarak oluşturmalısınız. Bunu düşün.

Kullanmayın foreach ifade veya JSON dönüşümleri kullanmayın. Bunu planlıyorsanız, yine bir nesneyle değil, bir veri yapısıyla çalışıyorsunuz.

Gerçekten ihtiyacınız varsa, temiz ve bakımı kolay bir koda sahip olmak için nesne yönelimli bir yaklaşım kullanın. Örneğin:

Dizi olarak nesne

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

Tüm özelliklere ihtiyacınız varsa bir aktarım nesnesi kullanın:

class PersonTransferObject
{
    private $person;

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

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

 }

6

Sonucu almak için bu işlevi kolayca kullanabilirsiniz:

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 veya üstünü kullanın .


5

İşte PHP nesnelerini ilişkilendirilebilir bir diziye dönüştürmek için özyinelemeli PHP işlevi:

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

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

Kullanım örneği:

// ---- 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
.. veya oneliner:$new_arr1 = (array) $my_object;
FooBar

1
Oneliner versiyonu sığ, yani eşdeğer değil.
Jonathan Lidbeck

5

Bir nesneyi diziye dönüştürmek için onu açıkça kullanın:

$name_of_array = (array) $name_of_object;

5

PHP'de bir nesne dizisini dönüştürmek için bir işlev de oluşturabilirsiniz:

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

@ Akintunde-Rotimi, ortak bir işlev yarattım ve gösterdim.
Rakhi Prajapati

4

Veritabanlarından nesne olarak veri aldığınızda bunu yapmak isteyebilirsiniz:

// 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
1 veya 10, 41 değil, 41 upvotes ile kabul edilmiş bir cevap var. Cevabınız buna ne katıyor?
Yaroslav

4

StdClass'ı bir diziye dönüştürmek için özel işlev:

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'a dönüştürmek için başka bir özel işlev:

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

Kullanım Örneği:

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

kullanın:

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

Özel karakterler ve sınıf adları olmayan bir dizi döndürür.


4

Bu cevap sadece bu yazının farklı cevaplarının birleşimidir, ancak basit değerleri veya dizileri olan genel veya özel özelliklere sahip bir PHP nesnesini ilişkilendirilebilir bir diziye dönüştürmenin çözümü ...

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

"İyi bilme" koduna bazı gelişmeler

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

İşlevi, bir sınıfın üyesi (yukarıdaki gibi) olup olmadığını değiştirmeleri gerektiğini Bildirimi __FUNCTION__için__METHOD__


3

Ayrıca Symfony Serializer Bileşenini de kullanabilirsiniz .

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

3

Durumunuz için "dekoratör" veya "tarih modeli dönüşümü" kalıplarını kullanmak doğru / güzeldi. Örneğin:

Modeliniz

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

Dekoratör

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

kullanım

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

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

Yani daha güzel ve daha doğru kod olacak.


3

Can sıkıcı yıldızları dönüştürme ve kaldırma:

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

Muhtemelen, yansımaları kullanmaktan daha ucuz olacaktır.


2

@ SpYk3HH'nin kısa çözümü

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

    return $a;
}

2

Birçok kişi bu soruyu bir nesnenin dinamik olarak erişim öznitelikleriyle ilgili sorun yaşadığından bulacağından, PHP'de bunu yapabileceğinizi belirteceğim: $valueRow->{"valueName"}

Bağlamda (okunabilirlik için HTML çıktısı kaldırıldı):

$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

Yazım kurallarını kullanarak sorununuzu çözebilirsiniz. Dönüş nesnenize aşağıdaki satırları eklemeniz yeterlidir:

$arrObj = array(yourReturnedObject);

Aşağıdakileri kullanarak yeni bir anahtar ve değer çifti de ekleyebilirsiniz:

$arrObj['key'] = value;

2

Nesneden diziye dönüştürme mantığını depolamak için özellikleri kullanmak iyi bir fikirdir. Basit bir örnek:

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

Bu cevabın Doktrin (veya benzeri) bir kayıt için hangisi olduğunu varsayıyorum.
nikoskip

1

Burada tekrar tekrar hangi noktaları içeren gibi, özyinelemeli nesnelerle de çalışan bir objectToArray () yöntemi yaptım$objectA$objectB$objectA .

Ayrıca ben ReflectionClass kullanarak genel özelliklere çıkış kısıtladı. İhtiyacınız yoksa ondan kurtulun.

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

Zaten kullanılan nesneleri tanımlamak için, adlandırılmış bu (soyut) sınıfta korumalı bir özellik kullanıyorum $this->usedObjects. Özyinelemeli iç içe bir nesne bulunursa, bunun yerine dize kullanılır **recursive**. Aksi takdirde sonsuz döngü nedeniyle başarısız olur.


$usedObjectsbaşlangıcında başlatılmaz, bu nedenle bunu birden çok kez çağırmak sonraki aramalarda yanlış sonuçlar verir. Ayrıca, sonunda serbest bırakmazsınız, böylece nesneleriniz asla bellekten kaldırılmaz.
HappyDog

1

Benim özel teklifim bile olan nesnelerde nesneleriniz varsa benim teklifim:

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

Ben (uygun anahtarlar ile gerekli özyinelemeli çözüm) kullanın:

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

Kullanım örneği, aşağıdaki kod:

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)

Bunu yazdıracak:

array(2) {
  ["bb"] => array(1) {
    ["two"] => int(22)
  }
  ["one"] => int(11)
}

Nesnelerin bir dizi nesneyi desteklemek için işlevinizi nasıl yükseltebiliriz?
celsowm
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.