web-dev-qa-db-ja.com

PHP-オブジェクトへの再帰的な配列?

PHPで多次元のarraystdClassオブジェクトに変換する方法はありますか?

_(object)_としてキャストすると、再帰的に動作しないようです。 json_decode(json_encode($array))は私が探している結果を生成しますが、もっと良い方法がなければなりません...

39
Peter

私が知る限り、これには事前に構築されたソリューションはないので、自分でロールすることができます:

function array_to_object($array) {
  $obj = new stdClass;
  foreach($array as $k => $v) {
     if(strlen($k)) {
        if(is_array($v)) {
           $obj->{$k} = array_to_object($v); //RECURSION
        } else {
           $obj->{$k} = $v;
        }
     }
  }
  return $obj;
} 
62
Jacob Relkin

私はこの答えが遅れるのを知っていますが、解決策を探している人のためにそれを投稿します。

このすべてのループなどの代わりに、PHPのネイティブjson_ *関数を使用できます。よく使う便利な機能がいくつかあります

/**
 * Convert an array into a stdClass()
 * 
 * @param   array   $array  The array we want to convert
 * 
 * @return  object
 */
function arrayToObject($array)
{
    // First we convert the array to a json string
    $json = json_encode($array);

    // The we convert the json string to a stdClass()
    $object = json_decode($json);

    return $object;
}


/**
 * Convert a object to an array
 * 
 * @param   object  $object The object we want to convert
 * 
 * @return  array
 */
function objectToArray($object)
{
    // First we convert the object into a json string
    $json = json_encode($object);

    // Then we convert the json string to an array
    $array = json_decode($json, true);

    return $array;
}

これが役に立てば幸い

42
Ole
function toObject($array) {
    $obj = new stdClass();
    foreach ($array as $key => $val) {
        $obj->$key = is_array($val) ? toObject($val) : $val;
    }
    return $obj;
}
7
Priya

あなたや他の多くの人が、JSON組み込み関数 json_decode() および json_encode() を指摘しています。あなたが言及した方法は機能しますが、完全ではありません:インデックス付き配列をオブジェクトに変換せず、インデックス付き配列として残ります。ただし、この問題を克服するトリックがあります。 JSON_FORCE_OBJECT 定数:

// Converts an array to an object recursively
$object = json_decode(json_encode($array, JSON_FORCE_OBJECT));

Tip:また、前述の here のように、JSON関数を使用してオブジェクトを配列に再帰的に変換できます。

// Converts an object to an array recursively
$array = json_decode(json_encode($object), true));    
4
MAChitgarha
/**
 * Recursively converts associative arrays to stdClass while keeping integer keys subarrays as arrays
 * (lists of scalar values or collection of objects).
 */
function a2o( array $array ) {
    $resultObj = new \stdClass;
    $resultArr = array();
    $hasIntKeys = false;
    $hasStrKeys = false;
    foreach ( $array as $k => $v ) {
        if ( !$hasIntKeys ) {
            $hasIntKeys = is_int( $k );
        }
        if ( !$hasStrKeys ) {
            $hasStrKeys = is_string( $k );
        }
        if ( $hasIntKeys && $hasStrKeys ) {
            $e = new \Exception( 'Current level has both integer and string keys, thus it is impossible to keep array or convert to object' );
            $e->vars = array( 'level' => $array );
            throw $e;
        }
        if ( $hasStrKeys ) {
            $resultObj->{$k} = is_array( $v ) ? a2o( $v ) : $v;
        } else {
            $resultArr[$k] = is_array( $v ) ? a2o( $v ) : $v;
        }
    }
    return ($hasStrKeys) ? $resultObj : $resultArr;
} 
3
Dmitriy Sintsov
public static function _arrayToObject($array) {
    $json = json_encode($array);
    $object = json_decode($json);
    return $object
}
3

連想配列をオブジェクトに変換する最も簡単な方法は次のとおりです。

まずjsonでエンコードし、次にデコードします。

$objectArray = json_decode(json_encode($associtiveArray));のように

3
Sunil

array_map再帰的に:

public static function _arrayToObject($array) {
    return is_array($array) ? (object) array_map([__CLASS__, __METHOD__], $array) : $array;
}

たとえばCarbonオブジェクトを基本的なstdClassにキャストしないので、私にとっては完璧に機能します(jsonエンコード/デコードが行います)。

3
Arno van Oordt

ここに掲載されている他のソリューションの一部は、シーケンシャル配列(JSでは_[]_)とマップ(JSでは_{}_)を区別できません。多くの使用例では、区別することが重要ですPHPすべての連続する数値キーを持つ配列(そのままにする必要があります)、数値キーがないPHP配列から、オブジェクトに変換する必要があります。 (以下の私の解決策は、上記の2つのカテゴリに該当しない配列では定義されていません。)

json_decode(json_encode($x))メソッドは2つのタイプを正しく処理しますが、最速のソリューションではありません。それでもまともですが、サンプルデータの実行ごとに合計25µs(平均100万回以上の実行からループオーバーヘッドを差し引いたもの)。

私は再帰的コンバーターのいくつかのバリエーションをベンチマークし、次のようになりました。すべての配列とオブジェクトを再構築します(ディープコピーを実行します)が、配置されている配列を変更する代替ソリューションよりも高速であるようです。それは私のサンプルデータの実行ごとに11µsでクロックします:

_function array_to_object($x) {
    if (!is_array($x)) {
        return $x;
    } elseif (is_numeric(key($x))) {
        return array_map(__FUNCTION__, $x);
    } else {
        return (object) array_map(__FUNCTION__, $x);
    }
}
_

これはインプレースバージョンです。小さな部分のみを変換する必要がある一部の大きな入力データでは高速かもしれませんが、私のサンプルデータでは、実行ごとに15µsがかかりました:

_function array_to_object_inplace(&$x) {
    if (!is_array($x)) {
        return;
    }
    array_walk($x, __FUNCTION__);
    reset($x);
    if (!is_numeric(key($x))) {
        $x = (object) $x;
    }
}
_

array_walk_recursive()を使用してソリューションを試していない

2
Tobia

私が思いつくことができる最短のもの:

array_walk_recursive($obj, function (&$val) { if (is_object($val)) $val = get_object_vars($val); });
0
felixfbecker

PHP内部(浅い)配列からオブジェクトへの型キャストメカニズムを使用するインプレースの深い配列からオブジェクトへの変換を行う関数です。必要な場合にのみ新しいオブジェクトを作成し、最小化します。データの複製。

function toObject($array) {
    foreach ($array as $key=>$value)
        if (is_array($value))
            $array[$key] = toObject($value);
    return (object)$array;
}

警告-循環参照のリスクがある場合は、このコードを使用しないでください。

0
rustyx

EDIT:この関数は、オブジェクトから配列への変換です。

から https://forrst.com/posts/PHP_Recursive_Object_to_Array_good_for_handling-0ka

protected function object_to_array($obj)
{
    $arrObj = is_object($obj) ? get_object_vars($obj) : $obj;
    foreach ($arrObj as $key => $val) {
            $val = (is_array($val) || is_object($val)) ? $this->object_to_array($val) : $val;
            $arr[$key] = $val;
    }
    return $arr;
}
0
Kamil

遅くなりましたが、JSONエンコーディング/デコーディングを使用して配列から/配列に完全に変換できることをお伝えしたいと思います。

//convert object $object into array
$array = json_decode(json_encode($object), true);
//convert array $array into object
$object = json_decode(json_encode($array));

json_encode関数とjson_decode関数は、php 5.2以降で使用できます。

0
mhh1422

これは、深さの大きい連想配列を処理でき、配列にないオブジェクトプロパティを上書きしない、スムーズな方法です。

    <?php

    function setPropsViaArray( $a, $o )
    {
        foreach ( $a as $k => $v )
        {
            if ( is_array( $v ) )
            {
                $o->{$k} = setPropsViaArray( $v, ! empty ( $o->{$k} ) ? $o->{$k} : new stdClass() );
            }
            else
            {
                $o->{$k} = $v;
            }
        }
        return $o;
    };

    setPropsViaArray( $newArrayData, $existingObject );
0
John Foley