Chuyển đổi một đối tượng PHP thành một mảng kết hợp


760

Tôi đang tích hợp API vào trang web của mình, hoạt động với dữ liệu được lưu trữ trong các đối tượng trong khi mã của tôi được viết bằng mảng.

Tôi muốn một hàm nhanh và bẩn để chuyển đổi một đối tượng thành một mảng.

Câu trả lời:


1392

Chỉ cần gõ nó

$array = (array) $yourObject;

Từ mảng :

Nếu một đối tượng được chuyển đổi thành một mảng, kết quả là một mảng có các phần tử là thuộc tính của đối tượng. Các khóa là tên biến thành viên, với một vài ngoại lệ đáng chú ý: thuộc tính số nguyên không thể truy cập được; các biến riêng có tên lớp được đặt trước tên biến; các biến được bảo vệ có '*' được đặt trước tên biến. Các giá trị được chuẩn bị này có byte rỗng ở hai bên.

Ví dụ: Đối tượng đơn giản

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

var_dump( (array) $object );

Đầu ra:

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

Ví dụ: Đối tượng phức tạp

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

Đầu ra (với \ 0s được chỉnh sửa cho rõ ràng):

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

Đầu ra với var_exportthay vì var_dump:

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

Kiểu chữ theo cách này sẽ không thực hiện việc truyền sâu vào biểu đồ đối tượng và bạn cần áp dụng các byte rỗng (như được giải thích trong trích dẫn thủ công) để truy cập bất kỳ thuộc tính không công khai nào. Vì vậy, điều này hoạt động tốt nhất khi truyền các đối tượng StdClass hoặc các đối tượng chỉ có các thuộc tính công cộng. Để nhanh và bẩn (những gì bạn yêu cầu) thì tốt thôi.

Cũng xem bài viết chuyên sâu này:


3
Cũng xem xét ArrayAccessgiao diện, có lẽ kết hợp với giải pháp này. php.net/manual/en/class.arrayaccess.php
alttag

3
Nếu bạn có các khóa số nguyên, nó sẽ được chuyển đổi thành chuỗi và điều này có thể gây ra vấn đề lớn. Ví dụ: [1 => "one"]trở thành["1" => "one"]
Oleg

2
@Howie typecasting với (array)(object)hoạt động đáng tin cậy và giống nhau trên tất cả các phiên bản kể từ PHP 4.3. Xem 3v4l.org/X6lhm . Nếu bạn gặp lỗi cú pháp, bạn đã làm sai.
Gordon

2
@Howie xem phần Changelog choempty . Bạn không thể sử dụng biểu thức có emptytrước 5.5. Điều này hoàn toàn không liên quan đến typecasting;)
Gordon

4
Kiểu chữ. Đúng. Gõ Freakin! Tốt +1
Kaushik Makwana

346

Bạn có thể nhanh chóng chuyển đổi các đối tượng được lồng sâu vào các mảng kết hợp bằng cách dựa vào hành vi của các hàm mã hóa / giải mã JSON:

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

12
Đây là giải pháp tốt nhất nếu bạn muốn chuyển đổi đệ quy chuyên sâu đầy đủ (và tất nhiên không
bận

2
điều này hoàn toàn giúp tôi với hoàn cảnh của mình, cảm ơn rất nhiều.
Cesar Bielich

9
Trân trọng, tôi nghĩ nó vẫn hoạt động ... đừng quên đặt tham số thứ 2 thành đúng.
Kirk B

3
Tham số thứ hai đã giải quyết vấn đề, làm việc cho PHP 5.6.25. Cảm ơn!
Ju Oliveira

3
Hoạt động hoàn hảo cho các đối tượng lồng nhau! Cảm ơn!
Giai điệu

68

Từ lần truy cập đầu tiên của Google cho " đối tượng PHP đến mảng PGS ", chúng ta có điều này:

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

Nguồn tại mãnippets.joyent.com .


16
Cá nhân, tôi không thích ý tưởng gọi lại hàm cho mọi giá trị. Tôi có một phiên bản tương tự, nhưng trong 3 dòng: function objectToArray($o) { $a = array(); foreach ($o as $k => $v) $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v; return $a; }Điều này chỉ đặt bất cứ thứ gì không phải là một đối tượng hoặc mảng và tiếp tục mà không cần gọi lại phương thức trừ khi cần thiết.
SpYk3HH

13
@ SpYk3HH: viết câu trả lời của riêng bạn?
DanMan

2
Lần truy cập đầu tiên cho "đối tượng php vào mảng PGS" là stackoverflow.com/questions/4345554/ Khăn
Chris

Điều này (và phiên bản từ @ SpYk3HH) dường như thậm chí còn hoạt động chậm hơn so với tùy chọn json_encode ( stackoverflow.com/a/16111687/470749 ). Tôi không biết tại sao những cách tiếp cận này sẽ được ưa thích hơn.
Ryan

1
@Ryan json mã hóa và giải mã sẽ không hoạt động với các giá trị NaN và INFINITE cho float và có thể có các vấn đề khác mà tôi không thể nghĩ ra từ đỉnh đầu nhưng trong nhiều trường hợp, đó có thể là một lựa chọn tốt hơn. Để tối ưu hóa, những gì nó cần là bối cảnh - hãy để tôi cắm một bài đăng tôi đã viết về chủ đề này evidentlycube.com/blog/game-optimization/when-to-optizes . Tuy nhiên, đừng tối ưu hóa những thứ không chiếm nhiều thời gian hoạt động vì lợi ích là vô nghĩa trong bối cảnh của toàn bộ ứng dụng.
Maurycy

61

Nếu thuộc tính đối tượng của bạn là công khai, bạn có thể làm:

$array =  (array) $object;

Nếu chúng là riêng tư hoặc được bảo vệ, chúng sẽ có các tên khóa lạ trên mảng. Vì vậy, trong trường hợp này bạn sẽ cần chức năng sau:

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

Nếu thuộc tính của bạn được bảo vệ, liệu setAccessible (false) có thể thay đổi trở lại thành khả năng hiển thị được bảo vệ không? hoặc nó sẽ làm cho nó riêng tư?
Nick Mitchell

Giải pháp duy nhất tôi tìm thấy, đã làm việc với các thuộc tính được bảo vệ. Cảm ơn
dav

3
giải pháp tốt nhất cho các biến riêng tư và được bảo vệ !!
HIRA THAKUR

Ở đây dòng $ property-> setAccessible (false); sẽ được thực thi trên mọi tài sản - ngay cả khi nó được công khai ...
Francois Bourgeois

Tuyệt vời ... Tuyệt vời ... Tuyệt vời. Cảm ơn.
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());

Đầu ra

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

1
Pro và nhược điểm của giải pháp này? Điều gì về một lớp được khai báo là Kiểm tra lớp {const A = 1; công khai $ cha = kiểm tra mới (); }
Matteo Gaggiano

13

Đây là một số mã:

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

hoạt động tốt nhất với tôi (nhưng tôi cần xóa 'xxx' và trả lại dữ liệu $)
Gerfried

12

Tất cả các câu trả lời khác được đăng ở đây chỉ hoạt động với các thuộc tính công cộng. Đây là một giải pháp hoạt động với các đối tượng giống như JavaBeans bằng cách sử dụng sự phản chiếu và getters:

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

Phải, nhưng ... nếu bạn đang sử dụng Object / Array làm biến, đó cũng là điều tất cả những điều này dẫn đến, tại sao bạn cần bất cứ thứ gì ngoài các publicthuộc tính?
SpYk3HH

@ SpYk3HH: Tôi không đặt câu hỏi. Tôi thậm chí không biết tại sao mọi người thích một mảng hơn một đối tượng ở vị trí đầu tiên.
Francois Bourgeois

Ơ, tôi thường thích chuyển đổi kết quả truy vấn thành mảng chỉ để cung cấp một "danh sách" thống nhất để lặp qua, vì hầu hết mọi thứ khác trong một ứng dụng phải được "lặp" có xu hướng là mảng. Chỉ cần làm cho nó dễ dàng để viết "phương pháp vòng lặp phổ quát". Thông thường, nếu tôi đang sử dụng một đối tượng, tôi sẽ không lặp qua các thuộc tính của nó, tôi đang sử dụng nó như một đối tượng và sử dụng các thuộc tính đó khi cần thiết.
SpYk3HH

11

Thế còn get_object_vars($obj) ? Nó có vẻ hữu ích nếu bạn chỉ muốn truy cập các thuộc tính công cộng của một đối tượng.

Xem get_object_vars .


10

Nhập cast đối tượng của bạn vào một mảng.

$arr =  (array) $Obj;

Nó sẽ giải quyết vấn đề của bạn.


5
Không, nó sẽ không, nếu bạn có tài sản riêng tư hoặc được bảo vệ.
forsberg

2
Giải pháp đơn giản nhất. Cảm ơn
ASD

6

Trước hết, nếu bạn cần một mảng từ một đối tượng, trước tiên bạn có thể cấu thành dữ liệu dưới dạng một mảng. Hãy suy nghĩ về nó.

Đừng dùng foreach câu lệnh hoặc biến đổi JSON. Nếu bạn đang lập kế hoạch này, một lần nữa bạn sẽ làm việc với cấu trúc dữ liệu, không phải với một đối tượng.

Nếu bạn thực sự cần nó, hãy sử dụng một cách tiếp cận hướng đối tượng để có một mã sạch và có thể bảo trì. Ví dụ:

Đối tượng như mảng

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

Nếu bạn cần tất cả các thuộc tính, sử dụng một đối tượng chuyển:

class PersonTransferObject
{
    private $person;

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

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

 }

6

Bạn có thể dễ dàng sử dụng chức năng này để nhận kết quả:

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

Sử dụng PHP 5 trở lên.


5

Đây là hàm PHP đệ quy của tôi để chuyển đổi các đối tượng PHP thành một mảng kết hợp:

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

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

Ví dụ sử dụng:

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

1
Phiên bản oneliner nông, nên không tương đương.
Jonathan Lidbeck

5

Để chuyển đổi một đối tượng thành mảng, chỉ cần bỏ nó một cách rõ ràng:

$name_of_array = (array) $name_of_object;

5

Bạn cũng có thể tạo một hàm trong PHP để chuyển đổi một mảng đối tượng:

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

@ Akintunde-Rotimi, tôi đã tạo một chức năng chung và hiển thị.
Rakhi Prajapati

4

Bạn có thể muốn làm điều này khi bạn lấy dữ liệu dưới dạng đối tượng từ cơ sở dữ liệu:

// 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
Có một câu trả lời được chấp nhận với 41 upvote, không phải 1 hay 10, 41. Câu trả lời của bạn thêm vào điều gì?
Yaroslav

4

Hàm tùy chỉnh để chuyển đổi stdClass thành một mảng:

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

Một chức năng tùy chỉnh khác để chuyển đổi Array thành 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;
    }
}

Ví dụ sử dụng:

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

Sử dụng:

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

Nó trả về một mảng không có ký tự đặc biệt và tên lớp.


4

Câu trả lời này chỉ là sự kết hợp của các câu trả lời khác nhau của bài đăng này, nhưng đó là giải pháp để chuyển đổi một đối tượng PHP có thuộc tính công khai hoặc riêng tư với các giá trị hoặc mảng đơn giản thành một mảng kết hợp ...

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

Một số điều khoản đối với mã "well-knwon"

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

Lưu ý rằng nếu hàm là thành viên của một lớp (như trên), bạn phải đổi __FUNCTION__thành__METHOD__


3

Ngoài ra, bạn có thể sử dụng Thành phần nối tiếp Symfony

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

Đối với trường hợp của bạn, điều đó đúng / đẹp nếu bạn sử dụng các mẫu "trang trí mô hình" hoặc "chuyển đổi mô hình ngày". Ví dụ:

Mô hình của bạn

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

Người trang trí

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

Sử dụng

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

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

Vì vậy, nó sẽ đẹp hơn và đúng mã hơn.


3

Chuyển đổi và loại bỏ các ngôi sao gây phiền nhiễu:

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

Có lẽ, nó sẽ rẻ hơn so với sử dụng phản xạ.


2

Giải pháp ngắn gọn của @ 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

Vì nhiều người tìm thấy câu hỏi này vì gặp rắc rối với các thuộc tính truy cập động của một đối tượng, tôi sẽ chỉ ra rằng bạn có thể làm điều này trong PHP: $valueRow->{"valueName"}

Trong ngữ cảnh (loại bỏ đầu ra HTML để dễ đọc):

$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

Bằng cách sử dụng typecasting bạn có thể giải quyết vấn đề của bạn. Chỉ cần thêm các dòng sau vào đối tượng trả về của bạn:

$arrObj = array(yourReturnedObject);

Bạn cũng có thể thêm một cặp khóa và giá trị mới vào nó bằng cách sử dụng:

$arrObj['key'] = value;

2

Tôi nghĩ rằng đó là một ý tưởng hay để sử dụng các đặc điểm để lưu trữ logic chuyển đổi đối tượng sang mảng. Một ví dụ đơn giản:

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

Tôi cho rằng câu trả lời này là dành cho hồ sơ Học thuyết (hoặc tương tự).
nikoskip

1

Ở đây tôi đã tạo một phương thức objectToArray () , cũng hoạt động với các đối tượng đệ quy, như khi $objectAchứa $objectBđiểm nào lại $objectA.

Ngoài ra, tôi đã giới hạn đầu ra cho các thuộc tính công cộng bằng ReflectionClass. Loại bỏ nó, nếu bạn không cần nó.

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

Để xác định các đối tượng đã sử dụng, tôi đang sử dụng một thuộc tính được bảo vệ trong lớp (trừu tượng) này, được đặt tên $this->usedObjects. Nếu một đối tượng lồng nhau đệ quy được tìm thấy, nó sẽ được thay thế bằng chuỗi **recursive**. Nếu không, nó sẽ thất bại vì vòng lặp vô hạn.


$usedObjectskhông được khởi tạo khi bắt đầu, vì vậy việc gọi này nhiều lần sẽ cho kết quả không chính xác trong các cuộc gọi sau. Ngoài ra, bạn không giải phóng nó vào cuối, vì vậy các đối tượng của bạn sẽ không bao giờ bị xóa khỏi bộ nhớ.
HappyDog

1

Có đề xuất của tôi, nếu bạn có các đối tượng trong các đối tượng với cả các thành viên tư nhân:

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

Tôi sử dụng điều này (giải pháp đệ quy cần thiết với các phím thích hợp):

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

Ví dụ về cách sử dụng, đoạn mã sau:

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)

Sẽ in cái này:

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

Làm thế nào chúng ta có thể nâng cấp chức năng của bạn để hỗ trợ các đối tượng với mảng các đối tượng?
celsowm
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.