2011-01-25 46 views
25

多次元arrayをPHPのstdClassオブジェクトに変換する方法はありますか?PHP - オブジェクトへの再帰的な配列?

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

答えて

45

は、私の知る限り、このためのビルド済みのソリューションはありませんので、あなたは自分自身をロールバックすることができます。

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

PHP配列に空のキーがある可能性がありますが、オブジェクトには空のプロパティを設定することはできません。 'else'を' elseif($ k!== '') 'に変更する価値があります。 – Andy

+0

@Andy固定、ありがとう! –

+0

ちょうどelseifでできないことに気づいてくれてありがとう! – Andy

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

これは配列の空のキーに致命的なエラー(空のプロパティにアクセスできません)を生成します。 [Jacobの答えのstrlen]を観察してください(http://stackoverflow.com/questions/4790453/php-recursive-array-to-object#answer-4790485) –

30

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

このループのすべての代わりに、PHPのネイティブjson_ *関数を使用することができます。私はこれが参考に

+2

私は、質問はこのメソッドを参照しました。 – Peter

+0

私はそれを見落としてしまったことについて、正当な防衛はありません。/私ができることは、私の眼鏡をかけて、Steve Erkleを引用します。私はそれをしました! トピックに戻る:私の知識と私の謙虚な意見では、これはこれを行う最もクリーンで最適な方法です。私が間違っている場合は私を修正してください:) – Ole

+3

コードラインで判断しているなら最もクリーンかもしれませんが、オーバーヘッドがはるかに多くなります。 Jacob Relkinの答えはより効率的で簡単にコード化されています。 – Peter

0

することができ、私が使用して便利な機能をいくつ多く

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

希望はここではPHPの内部を使用してインプレース深い配列からオブジェクトへの変換を行うための機能だんです(浅い)アレイからオブジェクトへの型キャストメカニズム。 必要に応じて新しいオブジェクトを作成し、データの重複を最小限に抑えます。

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

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

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

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

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

$ arrObjがまだオブジェクトであれば返されないのはなぜですか? – guido

+0

私はquetionを誤解していたので、このfnはオブジェクトから配列への変換です。私は私の答えを更新します。 – Kamil

0

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

はここで素晴らしい深みを持つ連想配列を扱うことができ、配列に含まれていないオブジェクトのプロパティを上書きしません。それを行うには、滑らかな方法です。

<?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

私が思い付くことができ、最短:ここに掲載他のソリューションのいくつかは、マップから離れシーケンシャル配列に(何がJSで[]だろう)(JSで{}を伝えるために失敗

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

。 )多くのユースケースでは、数値キーを持たないPHP配列(オブジェクトに変換する必要がある)からすべての連続した数値キーを持つPHP配列を区別することが重要です。 (上記の2つのカテゴリに該当しない配列については、私の解決策は未定義です。)

json_decode(json_encode($x))メソッドは、2つの型を正しく処理しますが、最速の解決策ではありません。それは私のサンプルデータに25μsの実行につき合計、しかしまだまともだ(1Mを実行にわたって平均、マイナスループのオーバーヘッド。)

私は、再帰的なコンバータのバリエーションのカップルをベンチマークし、以下になってしまいました。すべてのアレイとオブジェクトを再構築します(ディープコピーを実行)が、アレイを変更する代替ソリューションよりも速いようです。それは私のサンプルデータに実行あたり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()

+0

最初のメソッドは、空のオブジェクトを作成しました。 2番目の方法は、一番外側の連想配列を 'stdClass'オブジェクトにすることだけでした。他のすべては内部的に配列のままです。 –

+0

@KimberlyW私は両方をテストしただけで、PHP 7でも動作します。[このサンプルを見る](http://sandbox.onlinephpfunctions.com/code/4fe7ffbed29c738f928ee5e3c13aee37471420ff) – Tobia

1

を使用して解決策を試してみませんでした

//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から始まる利用可能です:レイトが、ちょうどあなたがから/配列に完全に変換するために、JSONのエンコード/デコードを使用することができることを言及したかったです5.2

+1

これは質問自体で言及されています。 2012](https://stackoverflow.com/a/9185337/1218980)をご覧ください。 –

1

あなたは再帰的にarray_mapを使用することができます。それは基本的なstdClassのに例のカーボンオブジェクトにキャストしていないので

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

は私にとって完璧な作品(JSONエンコード/デコードん)

+0

これは、クラス内でこのタイプのユーティリティが必要なときに、シンプルで甘く便利です。その参照は見つけるのが難しいです。明確にするために、サンプルクラスにラップしてください。そうでなければ、__CLASS__、__METHOD__という魔法の良い例です...あなたはそれを頻繁に見ません。 – ChrisN

0
public static function _arrayToObject($array) { 
    $json = json_encode($array); 
    $object = json_decode($json); 
    return $object 
} 
関連する問題