如何将数组转换为PHP中的对象?
我如何转换这样的数组对象?
[128] =>数组 ( [状态] =>图A. Facebook的水平滚动条以1024x768的屏幕分辨率显示。 ) [129] =>数组 ( 在工作的那天,我有一些闲暇时间 ) )
在最简单的情况下,将数组“转换”为对象可能就足够了:
$object = (object) $array;
另一个选择是将一个标准类实例化为一个变量,并在重新赋值时遍历数组:
$object = new stdClass(); foreach ($array as $key => $value) { $object->$key = $value; }
正如Edson Medina指出的那样,一个非常干净的解决方案是使用内置的json_
函数:
$object = json_decode(json_encode($array), FALSE);
这也(递归)将所有的子数组转换成对象,你可能想也可能不想要。 不幸的是,它在循环方法上有2-3倍的性能 。
警告! (感谢Ultra的评论):
不同环境下的json_decode以不同的方式转换UTF-8数据。 我最终在本地生产“240.00”,在生产中生产“240”,这是巨大的消耗。 Morover如果转换失败,则字符串get的返回值为NULL
您可以简单地使用类型转换将数组转换为对象。
// *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;
这里有三种方法:
-
假一个真实的对象:
class convert { public $varible; public function __construct($array) { $this = $array; } public static function toObject($array) { $array = new convert($array); return $array; } }
-
通过将数组转换为对象将数组转换为对象:
$array = array( // ... ); $object = (object) $array;
-
手动将数组转换为对象:
$object = object; foreach ($arr as $key => $value) { $object->{$key} = $value; }
快速入门:
// assuming $var is a multidimensional array $obj = json_decode (json_encode ($var), FALSE);
不漂亮,但工程。
简单的方法是
$object = (object)$array;
但那不是你想要的。 如果你想要的对象,你想实现的东西,但在这个问题是缺少的。 仅仅为了使用对象而使用对象是没有意义的。
根据你需要的地方以及如何访问对象,有不同的方法来做到这一点。
例如:只是形式化它
$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. ..."
它的方式很简单,这也将为递归数组创建一个对象:
$object = json_decode(json_encode((object) $yourArray), FALSE);
这个为我工作
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; }
就我所知,没有内置的方法可以实现,但是就像一个简单的循环一样简单:
$obj= new stdClass(); foreach ($array as $k=> $v) { $obj->{$k} = $v; }
如果你需要它递归地构建你的对象,你可以阐述一下。
其实如果你想用这个多维数组,你会想使用一些递归。
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; }
我会毫不犹豫地用这样一个干净的方式:
<?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(); ?>
如果您提交:
你会得到这个:
我发现这比上面的答案更符合逻辑对象应该用于他们的目的(封装可爱的小对象)。
同样使用get_object_vars确保在被操纵的对象中没有创建额外的属性(你不想要一个有姓氏的汽车,也不需要一个人操作四个轮子)。
递归是你的朋友:
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($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')
你也可以使用一个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
使用我所做的这个功能:
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);
你也可以通过在变量左边添加(对象)来创建一个新的对象。
<?php $a = Array ( 'status' => " text" ); var_dump($a); $b = (object)$a; var_dump($b); var_dump($b->status);
使用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 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; } }
如果你使用不同的方法,你会有问题。 这是最好的方法。 你曾经见过。
受到所有这些代码的启发,我尝试创建一个支持以下特性的增强版本:特定的类名称,避免构造方法,“bean”模式和严格模式(仅设置现有属性):
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; } } }
码
这个函数与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,))
一点复杂但容易延伸的技术:
假设你有一个数组
$a = [ 'name' => 'ankit', 'age' => '33', 'dob' => '1984-04-12' ];
假设你有一个人类,可能有更多或更少的属性从这个数组中。 例如
class Person { private $name; private $dob; private $age; private $company; private $city; }
如果你还想把你的数组改为人物。 你可以使用ArrayIterator类。
$arrayIterator = new \ArrayIterator($a); // Pass your array in the argument.
现在你有了迭代器对象。
创建一个扩展FilterIterator类的类; 你必须定义抽象方法accept。 根据例子
class PersonIterator extends \FilterIterator { public function accept() { return property_exits('Person', parent::current()); } }
上述推理只有在类中存在时才会绑定该属性。
在PersonIterator类中添加一个更多的方法
public function getObject(Person $object) { foreach ($this as $key => $value) { $object->{'set' . underscoreToCamelCase($key)}($value); } return $object; }
确保你在你的类中定义了mutators。 现在您已经准备好在要创建对象的位置调用这些函数。
$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));
CakePHP有一个递归的Set :: map类,它基本上把一个数组映射到一个对象中。 您可能需要更改数组的外观,以便使对象看起来像您想要的样子。
http://api.cakephp.org/view_source/set/#line-158
最坏的情况下,你可能会从这个函数中得到一些想法。
显然只是一些其他人的答案外推,但这里是递归函数,将任何覆盖维数组转换为一个对象:
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
)在结果对象中引用它们。
我用相当简单的方法做到了,
$list_years = array(); $object = new stdClass(); $object->year_id = 1 ; $object->year_name = 2001 ; $list_years[] = $object;
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; }
通过使用(数组)和(对象)作为前缀,您可以简单地将对象数组转换为标准数组和副词
<?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>'; ?>
我使用以下来将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" } } ] } } }
这需要PHP7,因为我选择使用lambda函数来锁定main函数中的'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); }