Câu trả lời:
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_export
thay 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:
[1 => "one"]
trở thành["1" => "one"]
(array)
và (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.
empty
. Bạn không thể sử dụng biểu thức có empty
trước 5.5. Điều này hoàn toàn không liên quan đến typecasting;)
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);
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 .
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.
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;
}
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"
}
Đâ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;
}
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;
}
public
thuộc tính?
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 .
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();
];
}
}
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.
Đâ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);
$new_arr1 = (array) $my_object;
Để 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;
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;
}
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;
}
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);
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.
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;
}
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__
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);
Đố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.
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ạ.
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 .= " ";
}
}
}
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;
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());
$Menu = new Admin_Model_DbTable_Menu();
$row = $Menu->fetchRow($Menu->select()->where('id = ?', $id));
$Addmenu = new Admin_Form_Addmenu();
$Addmenu->populate($row->toArray());
Ở đâ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 $objectA
chứ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.
$usedObjects
khô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ớ.
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;
}
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)
}
ArrayAccess
giao diện, có lẽ kết hợp với giải pháp này. php.net/manual/en/class.arrayaccess.php