我正在集成一个API到我的网站,它与存储在对象中的数据一起工作,而我的代码是使用数组编写的。

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


当前回答

如果你的对象属性是公共的,你可以这样做:

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

其他回答

下面是一些代码:

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

Use:

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

它返回一个没有特殊字符和类名的数组。

下面是将PHP对象转换为关联数组的递归PHP函数:

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

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

使用的例子:

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

由于很多人发现这个问题是因为在动态访问对象属性时遇到了麻烦,我只想指出,你可以在PHP中这样做:

在上下文(删除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 .= " ";
        }
    }
}

只是对它进行类型转换

$array = (array) $yourObject;

从数组:

如果将一个对象转换为数组,则结果是一个数组,其元素是该对象的属性。键是成员变量名,但有几个明显的例外:整数属性不可访问;私有变量的类名在变量名之前;受保护变量的变量名前面有一个'*'。这些前置值的两边都是空字节。

示例:简单对象

$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(
  )),
)

以这种方式进行类型转换不会对对象图进行深度转换,您需要应用null字节(如手册引用中所解释的那样)来访问任何非公共属性。因此,当强制转换StdClass对象或只有公共属性的对象时,这种方法效果最好。快速和肮脏(你所要求的)是可以的。

也可以看看这篇深入的博客文章:

快速PHP对象到数组的转换