如何在PHP中转换数组为对象?

如何将这样的数组转换为对象?

[128] => Array
(
[status] => "Figure A.
Facebook's horizontal scrollbars showing up on a 1024x768 screen resolution."
)


[129] => Array
(
[status] => "The other day at work, I had some spare time"
)
1007806 次浏览

简单的方法是

$object = (object)$array;

但这不是你想要的。如果你想要对象,你想要实现一些东西,但这在这个问题中是缺失的。仅仅为了使用对象而使用对象是没有意义的。

在最简单的情况下,将数组“强制转换”为对象可能就足够了:

$object = (object) $array;

另一个选择是实例化一个标准类作为一个变量,循环遍历你的数组,同时重新分配值:

$object = new stdClass();
foreach ($array as $key => $value)
{
$object->$key = $value;
}

正如埃德森麦地那指出的那样,一个真正干净的解决方案是使用内置的json_函数:

$object = json_decode(json_encode($array), FALSE);

这也(递归地)将所有子数组转换为对象,这可能是你想要的,也可能不是。不幸的是,它在循环方法上有2-3x 的性能影响

警告!(感谢Ultra的评论):

不同环境上的json_decode以不同的方式转换UTF-8数据。我最终在当地得到了“240.00”的值,在生产中得到了“240”——巨大的灾难。此外,如果转换失败,字符串get返回为NULL

据我所知,没有内置的方法可以做到这一点,但它就像一个简单的循环一样简单:

    $obj= new stdClass();


foreach ($array as $k=> $v) {
$obj->{$k} = $v;
}

如果你需要递归地构建你的对象,你可以详细说明。

CakePHP有一个递归的Set::map类,基本上是将数组映射到对象。为了使对象看起来像你想要的样子,你可能需要改变数组的样子。

http://api.cakephp.org/view_source/set/#line-158

最坏的情况下,您可能会从这个函数中得到一些想法。

这里有三种方法:

  1. 伪造一个真实的物体:

    class convert
    {
    public $varible;
    
    
    public function __construct($array)
    {
    $this = $array;
    }
    
    
    public static function toObject($array)
    {
    $array = new convert($array);
    return $array;
    }
    }
    
  2. Convert the array into an object by casting it to an object:

    $array = array(
    // ...
    );
    $object = (object) $array;
    
  3. Manually convert the array into an object:

    $object = object;
    foreach ($arr as $key => $value) {
    $object->{$key} = $value;
    }
    

这个方法对我很管用

  function array_to_obj($array, &$obj)
{
foreach ($array as $key => $value)
{
if (is_array($value))
{
$obj->$key = new stdClass();
array_to_obj($value, $obj->$key);
}
else
{
$obj->$key = $value;
}
}
return $obj;
}


function arrayToObject($array)
{
$object= new stdClass();
return array_to_obj($array,$object);
}

用法:

$myobject = arrayToObject($array);
print_r($myobject);

返回:

    [127] => stdClass Object
(
[status] => Have you ever created a really great looking website design
)


[128] => stdClass Object
(
[status] => Figure A.
Facebook's horizontal scrollbars showing up on a 1024x768 screen resolution.
)


[129] => stdClass Object
(
[status] => The other day at work, I had some spare time
)

像往常一样,你可以这样循环:

foreach($myobject as $obj)
{
echo $obj->status;
}

实际上,如果你想在多维数组中使用这个你就需要使用一些递归。

static public function array_to_object(array $array)
{
foreach($array as $key => $value)
{
if(is_array($value))
{
$array[$key] = self::array_to_object($value);
}
}
return (object)$array;
}

快速攻击:

// assuming $var is a multidimensional array
$obj = json_decode (json_encode ($var), FALSE);

不漂亮,但很好用。

显然,这只是对其他人答案的推断,但这里有一个递归函数,可以将任何多维数组转换为对象:

   function convert_array_to_object($array){
$obj= new stdClass();
foreach ($array as $k=> $v) {
if (is_array($v)){
$v = convert_array_to_object($v);
}
$obj->{strtolower($k)} = $v;
}
return $obj;
}

并且记住,如果数组具有数字键,则仍然可以使用{}(例如:$obj->prop->{4}->prop)在结果对象中引用它们。

受到所有这些代码的启发,我尝试创建一个增强版本,支持:特定的类名,避免构造函数方法,'beans'模式和严格模式(仅设置现有属性):

    class Util {


static function arrayToObject($array, $class = 'stdClass', $strict = false) {
if (!is_array($array)) {
return $array;
}


//create an instance of an class without calling class's constructor
$object = unserialize(
sprintf(
'O:%d:"%s":0:{}', strlen($class), $class
)
);


if (is_array($array) && count($array) > 0) {
foreach ($array as $name => $value) {
$name = strtolower(trim($name));
if (!empty($name)) {


if(method_exists($object, 'set'.$name)){
$object->{'set'.$name}(Util::arrayToObject($value));
}else{
if(($strict)){


if(property_exists($class, $name)){


$object->$name = Util::arrayToObject($value);


}


}else{
$object->$name = Util::arrayToObject($value);
}


}


}
}
return $object;
} else {
return FALSE;
}
}
}

你也可以通过在变量的左边添加(对象)来创建一个新对象。

<?php
$a = Array
( 'status' => " text" );
var_dump($a);
$b = (object)$a;
var_dump($b);
var_dump($b->status);

http://codepad.org/9YmD1KsU

容易:

$object = json_decode(json_encode($array));

例子:

$array = array(
'key' => array(
'k' => 'value',
),
'group' => array('a', 'b', 'c')
);


$object = json_decode(json_encode($array));

那么,以下是正确的:

$object->key->k === 'value';
$object->group === array('a', 'b', 'c')

我肯定会用这样一种干净的方式:

<?php


class Person {


private $name;
private $age;
private $sexe;


function __construct ($payload)
{
if (is_array($payload))
$this->from_array($payload);
}




public function from_array($array)
{
foreach(get_object_vars($this) as $attrName => $attrValue)
$this->{$attrName} = $array[$attrName];
}


public function say_hi ()
{
print "hi my name is {$this->name}";
}
}


print_r($_POST);
$mike = new Person($_POST);
$mike->say_hi();


?>

如果你提交:

formulaire

你会得到这个:

mike

我发现这更符合逻辑的比较以上的答案从对象应该用于他们的目的(封装可爱的小对象)。

此外,使用get_object_vars确保在被操纵的对象中没有创建额外的属性(您不希望汽车有姓,也不希望人有4个轮子)。

根据你需要的位置和访问对象的方式有不同的方法。

例如:只需对它进行类型转换

$object =  (object) $yourArray;

然而,最兼容的方法是使用一个实用程序方法(还不是PHP的一部分),它实现了基于指定类型的字符串的标准PHP强制转换(或者忽略它,只是去引用值):

/**
* dereference a value and optionally setting its type
*
* @param mixed $mixed
* @param null  $type (optional)
*
* @return mixed $mixed set as $type
*/
function rettype($mixed, $type = NULL) {
$type === NULL || settype($mixed, $type);
return $mixed;
}

在你的案例中的用法示例(在线演示):

$yourArray = Array('status' => 'Figure A. ...');


echo rettype($yourArray, 'object')->status; // prints "Figure A. ..."

我用了很简单的方法,

    $list_years         = array();
$object             = new stdClass();


$object->year_id   = 1 ;
$object->year_name = 2001 ;
$list_years[]       = $object;

您可以简单地使用类型强制转换将数组转换为对象。

// *convert array to object* Array([id]=> 321313[username]=>shahbaz)
$object = (object) $array_name;


//now it is converted to object and you can access it.
echo $object->username;
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;
}


function array_to_object($data)
{
if (is_array($data) || is_object($data))
{
$result= new stdClass();
foreach ($data as $key => $value)
{
$result->$key = array_to_object($value);
}
return $result;
}
return $data;
}

你也可以使用ArrayObject,例如:

<?php
$arr = array("test",
array("one"=>1,"two"=>2,"three"=>3),
array("one"=>1,"two"=>2,"three"=>3)
);
$o = new ArrayObject($arr);
echo $o->offsetGet(2)["two"],"\n";
foreach ($o as $key=>$val){
if (is_array($val)) {
foreach($val as $k => $v) {
echo $k . ' => ' . $v,"\n";
}
}
else
{
echo $val,"\n";
}
}
?>


//Output:
2
test
one => 1
two => 2
three => 3
one => 1
two => 2
three => 3

通过使用(array)和(object)作为前缀,可以简单地将对象数组转换为标准数组,反之亦然

<?php
//defining an array
$a = array('a'=>'1','b'=>'2','c'=>'3','d'=>'4');


//defining an object array
$obj = new stdClass();
$obj->a = '1';
$obj->b = '2';
$obj->c = '3';
$obj->d = '4';


print_r($a);echo '<br>';
print_r($obj);echo '<br>';


//converting object array to array
$b = (array) $obj;
print_r($b);echo '<br>';


//converting array to object
$c = (object) $a;
print_r($c);echo '<br>';
?>

代码

此函数的工作原理与json_decode(json_encode($arr), false)相同。

function arrayToObject(array $arr)
{
$flat = array_keys($arr) === range(0, count($arr) - 1);
$out = $flat ? [] : new \stdClass();


foreach ($arr as $key => $value) {
$temp = is_array($value) ? $this->arrayToObject($value) : $value;


if ($flat) {
$out[] = $temp;
} else {
$out->{$key} = $temp;
}
}


return $out;
}

测试

测试1:平面阵列

$arr = ["a", "b", "c"];
var_export(json_decode(json_encode($arr)));
var_export($this->arrayToObject($arr));

输出:

array(
0 => 'a',
1 => 'b',
2 => 'c',
)
array(
0 => 'a',
1 => 'b',
2 => 'c',
)

测试2:对象数组

$arr = [["a" => 1], ["a" => 1], ["a" => 1]];
var_export(json_decode(json_encode($arr)));
var_export($this->arrayToObject($arr));

输出:

array(
0 => stdClass::__set_state(array('a' => 1,)),
1 => stdClass::__set_state(array('a' => 1,)),
2 => stdClass::__set_state(array('a' => 1,)),
)
array(
0 => stdClass::__set_state(array('a' => 1,)),
1 => stdClass::__set_state(array('a' => 1,)),
2 => stdClass::__set_state(array('a' => 1,)),
)

测试3:对象

$arr = ["a" => 1];
var_export(json_decode($arr));
var_export($this->arrayToObject($arr));

输出:

stdClass::__set_state(array('a' => 1,))
stdClass::__set_state(array('a' => 1,))

使用json_encode是有问题的,因为它处理非UTF-8数据的方式。值得注意的是,json_encode/json_encode方法也将非关联数组作为数组。这可能是你想要的,也可能不是。我最近需要重新创建这个解决方案的功能,但没有使用json_函数。这是我想到的:

/**
* Returns true if the array has only integer keys
*/
function isArrayAssociative(array $array) {
return (bool)count(array_filter(array_keys($array), 'is_string'));
}


/**
* Converts an array to an object, but leaves non-associative arrays as arrays.
* This is the same logic that `json_decode(json_encode($arr), false)` uses.
*/
function arrayToObject(array $array, $maxDepth = 10) {
if($maxDepth == 0) {
return $array;
}


if(isArrayAssociative($array)) {
$newObject = new \stdClass;
foreach ($array as $key => $value) {
if(is_array($value)) {
$newObject->{$key} = arrayToObject($value, $maxDepth - 1);
} else {
$newObject->{$key} = $value;
}
}
return $newObject;
} else {


$newArray = array();
foreach ($array as $value) {
if(is_array($value)) {
$newArray[] = arrayToObject($value, $maxDepth - 1);
} else {
$newArray[] = $value;
}
}
return $newArray;
}
}

递归是你的朋友:

function __toObject(Array $arr) {
$obj = new stdClass();
foreach($arr as $key=>$val) {
if (is_array($val)) {
$val = __toObject($val);
}
$obj->$key = $val;
}


return $obj;
}

它的方法很简单,这将为递归数组创建一个对象:

$object = json_decode(json_encode((object) $yourArray), FALSE);

世界上最好的方法:)

function arrayToObject($conArray)
{
if(is_array($conArray)){
/*
* Return array converted to object
* Using __FUNCTION__ (Magic constant)
* for recursive call
*/
return (object) array_map(__FUNCTION__, $conArray);
}else{
// Return object
return $conArray;
}
}

如果使用不同的方法,就会出现问题。这是最好的方法。你所见过的。

我使用以下代码将Yaml文件关联数组解析为对象状态。

这将检查所有提供的数组中是否隐藏有对象,并将它们转换为对象。

    /**
* Makes a config object from an array, making the first level keys properties a new object.
* Property values are converted to camelCase and are not set if one already exists.
* @param array $configArray Config array.
* @param boolean $strict To return an empty object if $configArray is not an array
* @return stdObject The config object
*/
public function makeConfigFromArray($configArray = [],$strict = true)
{
$object = new stdClass();


if (!is_array($configArray)) {
if(!$strict && !is_null($configArray)) {
return $configArray;
}
return $object;
}


foreach ($configArray as $name => $value) {
$_name = camel_case($name);
if(is_array($value)) {
$makeobject = true;
foreach($value as $key => $val) {
if(is_numeric(substr($key,0,1))) {
$makeobject = false;
}
if(is_array($val)) {
$value[$key] = $this->makeConfigFromArray($val,false);
}
}
if($makeobject) {
$object->{$name} = $object->{$_name} = $this->makeConfigFromArray($value,false);
}
else {
$object->{$name} = $object->{$_name} = $value;
}


}
else {
$object->{$name} = $object->{$_name} = $value;
}
}


return $object;
}

这将把yaml配置为

fields:
abc:
type: formfield
something:
- a
- b
- c
- d:
foo:
bar

到由以下数组组成的数组:

array:1 [
"fields" => array:1 [
"abc" => array:2 [
"type" => "formfield"
"something" => array:4 [
0 => "a"
1 => "b"
2 => "c"
3 => array:1 [
"d" => array:1 [
"foo" => "bar"
]
]
]
]
]
]

以…为目标:

{#325
+"fields": {#326
+"abc": {#324
+"type": "formfield"
+"something": array:4 [
0 => "a"
1 => "b"
2 => "c"
3 => {#328
+"d": {#327
+"foo": "bar"
}
}
]
}
}
}

使用我创建的这个函数:

function buildObject($class,$data){
$object = new $class;
foreach($data as $key=>$value){
if(property_exists($class,$key)){
$object->{'set'.ucfirst($key)}($value);
}
}
return $object;
}

用法:

$myObject = buildObject('MyClassName',$myArray);

有点复杂,但很容易扩展的技术:

假设你有一个数组

$a = [
'name' => 'ankit',
'age' => '33',
'dob' => '1984-04-12'
];

假设您有一个Person类,它可能有来自这个数组的或多或少的属性。例如

class Person
{
private $name;
private $dob;
private $age;
private $company;
private $city;
}

如果你还想把数组改成person对象。你可以使用ArrayIterator类。

$arrayIterator = new \ArrayIterator($a); // Pass your array in the argument.

现在你有了迭代器对象。

创建一个扩展FilterIterator class的类;你必须定义抽象方法accept。遵循示例

class PersonIterator extends \FilterIterator
{
public function accept()
{
return property_exists('Person', parent::current());
}
}

上面的实现只在类中存在该属性时才会绑定它。

在类PersonIterator中再添加一个方法

public function getObject(Person $object)
{
foreach ($this as $key => $value)
{
$object->{'set' . underscoreToCamelCase($key)}($value);
}
return $object;
}
确保在类中定义了mutator。 现在你已经准备好调用这些你想要创建object的函数
$arrayiterator = new \ArrayIterator($a);
$personIterator = new \PersonIterator($arrayiterator);


$personIterator->getObject(); // this will return your Person Object.

一个衬套

$object= json_decode(json_encode($result_array, JSON_FORCE_OBJECT));

这需要PHP7,因为我选择使用lambda函数来锁定主函数中的'innerfunc'。lambda函数是递归调用的,因此需要:"use (&$innerfunc)"。你可以在PHP5中这样做,但不能隐藏innerfunc。

function convertArray2Object($defs) {
$innerfunc = function ($a) use ( &$innerfunc ) {
return (is_array($a)) ? (object) array_map($innerfunc, $a) : $a;
};
return (object) array_map($innerfunc, $defs);
}

我使用的一个(它是类成员):

const MAX_LEVEL = 5; // change it as needed


public function arrayToObject($a, $level=0)
{


if(!is_array($a)) {
throw new InvalidArgumentException(sprintf('Type %s cannot be cast, array expected', gettype($a)));
}


if($level > self::MAX_LEVEL) {
throw new OverflowException(sprintf('%s stack overflow: %d exceeds max recursion level', __METHOD__, $level));
}


$o = new stdClass();
foreach($a as $key => $value) {
if(is_array($value)) { // convert value recursively
$value = $this->arrayToObject($value, $level+1);
}
$o->{$key} = $value;
}
return $o;
}

多维数组转换为对象。此代码用于转换必应搜索API的尝试和捕获方法。

try {
// Perform the Web request and get the JSON response
$context = stream_context_create($options);
$results = file_get_contents($url . "?cc=" . $country . "&category=" . $type, false, $context);
$results = json_decode($results);
return response()->json($results);
} catch (\Exception $e) {
$results = array('value' => array(
(object) array(
"name" => "Unable to Retrive News",
"url" => "http://www.sample.com/",
"image" => (object) array("thumbnail" => (object) array("contentUrl" => "")),
"publishedAt" => "",
"description" => "")
)
);
$results = (object) $results;
return response()->json($results);
}

你可以使用反射:

<?php


$array = ['name'=>'maria','age'=>33];


class Person {


public $name;
public $age;


public function __construct(string $name, string $age){
$this->name  = $name;
$this->age = $age;
}
}


function arrayToObject(array $array, string $class_name){


$r = new ReflectionClass($class_name);
$object = $r->newInstanceWithoutConstructor();
$list = $r->getProperties();
foreach($list as $prop){
$prop->setAccessible(true);
if(isset($array[$prop->name]))
$prop->setValue($object, $array[$prop->name]);
}


return $object;


}


$pessoa1 = arrayToObject($array, 'Person');
var_dump($pessoa1);

可以使用(object)函数将数组转换为对象。

$arr= [128=> ['status'=>
'Figure A. Facebook \'s horizontal scrollbars showing up on a 1024x768 screen resolution.'],
129=>['status'=>'The other day at work, I had some spare time']];


$ArrToObject=(object)$arr;
var_dump($ArrToObject);

结果将是一个包含数组的对象:

对象(stdClass)#1048(2){[128]=>数组(1){

< p >["地位"]= > 字符串(87)“图a: Facebook的水平滚动条显示在1024x768分辨率的屏幕上。”} < / p >

[129]=> array(1) { ["地位"]= > 字符串(44)"The other day at work, I have some spare time"}}

.

我也有这个问题,但我注意到json_decode将JSON数组转换为对象。

所以,我通过使用json_encode($PHPArray)来实现我的解决方案,它返回对象的JSON字符串,然后我用Json_decode($string)解码字符串,它将返回一个完美的结构化对象。 速记< / >强

$object = json_decode(json_encode($array));

$jsonString = json_encode($array);
$object = json_decode($jsonString);

如果你需要将一个数组强制转换为一个特定的类(在我的例子中,我需要对象类型为Google_Service_AndroidPublisher_Resource_Inappproducts),你可以像这样从stdClass中将类名str_replace为预期的类:

function castArrayToClass(array $array, string $className)
{
//first cast the array to stdClass
$subject = serialize((object)$array);
//then change the class name
$converted = str_replace(
'O:8:"stdClass"',
'O:'.strlen($className).':"'.$className.'"',
$subject
);
unset($subject);


return unserialize($converted);
}