提问



我正在将API集成到我的网站,该网站使用存储在对象中的数据,而我的代码是使用数组编写的。


我想要一个快速而又脏的函数将对象转换为数组。

最佳参考


只是强调它


$array =  (array) $yourObject;


来自http://www.php.net/manual/en/language.types.array.php [50]



  如果一个对象被转换为一个数组,结果就是一个数组,其元素是对象的属性。键是成员变量名,有一些值得注意的例外:整数属性是不可访问的;私有变量的类名是前置的变量名;受保护变量在变量名前加上*。这些前置值在任一侧都有空字节。



示例:简单对象


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

var_dump( (array) $object );


输出:


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


示例:复杂对象


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


输出(为清晰起见,编辑了\\ 0s):


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


输出var_export而不是var_dump:


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


以这种方式进行类型转换不会对对象图进行深度转换,您需要应用空字节(如手册中所述)来访问任何非公共属性。因此,在仅使用公共属性转换StdClass对象或对象时,这种方法效果最佳。为了快速和肮脏(你要求的)它很好。


另见这篇深入的博文:



  • http://ocramius.github.io/blog/fast-php-object-to-array-conversion/


其它参考1


您可以依靠JSON编码/解码函数的行为快速将深层嵌套对象转换为关联数组:[51]


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

其它参考2


从第一次谷歌搜索 php对象到关联数组我们有这个:


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


来自codesnippets.joyent.com。[52]

其它参考3


如果您的对象属性是公共的,您可以:


$array =  (array) $object;


如果它们是私有的或受保护的,它们将在阵列上具有奇怪的键名。因此,在这种情况下,您将需要以下功能:


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

其它参考4


此处发布的所有其他答案仅适用于公共属性。这是一个使用反射和getter与 javabean 类对象一起使用的解决方案:


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

其它参考5


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


输出


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

其它参考6


这是一些代码:


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

其它参考7


get_object_vars($obj)怎么样?如果您只想访问对象的公共属性,似乎很有用。
http://www.php.net/function.get-object-vars[53]

其它参考8


要将对象转换为数组,只需显式转换它


$name_of_array =  (array) $name_of_object;

其它参考9


嗨,


这是我的递归PHP函数,用于将PHP对象转换为关联数组


// --------------------------------------------------------- 
// ----- object_to_array_recusive --- 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_recusive ( $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_recusive($val); 
            } 
            else { 
                $res_arr[$akey] = (empty($val)) ? $empty : (string)$val; 
            } 

        $i++; 
        }

    } 

    return $res_arr;
}


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


用法示例:


// ---- return associative array from object, ... use: 
$new_arr1 = object_to_array_recusive($my_object); 
// -- or -- 
// $new_arr1 = object_to_array_recusive($my_object,TRUE); 
// -- or -- 
// $new_arr1 = object_to_array_recusive($my_object,1); 


// ---- return numeric array from object, ... use: 
$new_arr2 = object_to_array_recusive($my_object,FALSE); 

其它参考10


自定义函数将stdClass转换为数组:


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的自定义函数:


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


用法示例:


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

其它参考11


您还可以在PHP中创建函数来转换对象数组。


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

其它参考12


键入将对象转换为数组。


$arr =  (array) $Obj;


它会解决你的问题。

其它参考13


当您从数据库 - >获取数据作为对象时,您可能希望这样做


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

其它参考14


function readObject($object) {
    $name = get_class ($object);
    $name = str_replace('\\', "\\\\", $name); \\ Comment this line, if you dont 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;
}


返回没有特殊字符和类名的数组

其它参考15


首先,如果你需要一个来自对象的数组,你可能应该首先将数据构成数组。想一想。


不要使用foreach语句或JSON转换。如果你正在计划这个,那么你再次使用数据结构,而不是使用对象。


如果您确实需要它,请使用面向对象的方法来获得干净且可维护的代码。例如:


对象作为数组


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


如果您需要所有属性使用传输对象


class PersonTransferObject
{
    private $person;

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

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

 }

其它参考16


此函数可以将对象必需转换为数组关联


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


使用>= php5

其它参考17


转换和删除恼人的星星:


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


可能它会比使用反射更便宜。

其它参考18


对井代码的一些改进


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


请注意,如果函数是类的成员(如上所述),则必须将__FUNCTION__更改为__METHOD__

其它参考19


您也可以使用Symfony Serializer组件[54]


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

其它参考20


$Menu = new Admin_Model_DbTable_Menu(); 
$row = $Menu->fetchRow($Menu->select()->where('id = ?', $id));
$Addmenu = new Admin_Form_Addmenu(); 
$Addmenu->populate($row->toArray());

其它参考21


在这里,我创建了一个 objectToArray()方法,该方法也适用于递归对象,例如当$objectA包含$objectB并再次指向$objectA时。


另外,我已经使用ReflectionClass将输出限制为公共属性。如果你不需要它,摆脱它。


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


为了识别已经使用过的对象,我在这个(抽象)类中使用了一个受保护的属性,名为$this->usedObjects。如果找到递归嵌套对象,它将被字符串**recursive**替换。否则它会因为无限循环而失败。

其它参考22


这个答案只是这篇文章的不同答案的结合,但它是用关联数组中的简单值或数组转换具有公共或私有属性的PHP对象的解决方案...


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

其它参考23


@ SpYk3HH的简短解决方案


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

    return $a;
}

其它参考24


通过使用类型转换,您可以解决您的问题。
只需在返回对象中添加以下行:


$arrObj = array(yourReturnedObject);


您还可以使用以下命令为其添加新的键和值对:


$arrObj['key'] = value;

其它参考25


由于很多人因为动态访问对象的属性而遇到这个线程,我只想指出你可以在php中执行此操作:$valueRow->{"valueName"}


在Context中(为了便于阅读,删除了HTML输出):


$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 .= " ";
        }

    }

}

其它参考26


如果你的对象中有私人成员,那么我的建议是:


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