PHPで空の値からデフォルトオブジェクトを作成しますか?
On 12月 1, 2020 by admin次のコードを検討してください。
$car = (object)[ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car->{"other"}->{"exterior"}->{$key} = $prop; }
これは私が他のデータを反復処理しながら、一度に数レイヤーの深さでオブジェクトにプロパティを追加するのが好きです。存在しない場合は作成するだけで、存在する場合はオーバーライドします。完璧です!
残念ながら、これにより警告がスローされます:
空の値からデフォルトオブジェクトを作成する
プロパティが次のように存在するかどうかを最初に確認することで問題を解決できます:
foreach($exteriorProperties as $key => $prop){ if(!isset($car->other)) $car->other = (object)[]; if(!isset($car->other->exterior)) $car->other->exterior = (object)[]; $car->other->exterior->{$key} = $prop; }
これは私の理想ではありません解決。もっとエレガントな解決策があるかどうか疑問に思います。現在、私はこれを使用しています:
@$car->{"other"}->{"exterior"}->{$key} = $prop;
警告を抑制するためですが、将来の互換性について心配しています。
誰かがこのシナリオに対してより洗練された解決策を持っていますか?
コメント
- 'として配列を使用しないでください以下の答えは、オブジェクトを適切に使用することを示唆しています。配列はローカルコードにのみ適しています。ファイルまたはクラスの外部で共有されるということは、キーを手動で記述していることを意味し、キーを覚えておく必要があります。オートコンプリートを備えた優れたIDEと、ゲッター/セッターを備えたオブジェクトは、幸せな開発者の世界です。
回答
はい、配列を使用します。
$car = [ "general" => [ "interior" => [ "seats" => "destroyed" ] ] ]; $exteriorProperties = [ "hood" => "shiny", "windows" => "dirty" ]; foreach($exteriorProperties as $key => $prop){ $car["other"]["exterior"][$key] = $prop; } $car = (object) $car;
とにかく、オブジェクト変換は最も外側の配列のみを変換します。ネストされた配列は引き続き配列です。
\is_array($car->general); // true
とにかく形のないオブジェクトにする必要があるのはなぜですか?これらのオブジェクトのクラスを定義するか、配列として扱うのが簡単な答えです。
ところで、$car->{"other"}
は本当に奇妙な書き方です$car->other
…
コメント
- あなたは'正しいと思います。常に配列に閉じ込められるのは嫌いです。
$car->{'other'}
は、ほとんどのプロパティキーが文字列変数からのものであるためです。$car->{$var1}->{$var2}
回答
はい、回避できますすべてのデータを配列として処理することにより、条件付き操作を繰り返しました。
コード:(デモ)
$car = json_decode( json_encode( array_replace_recursive( (array)$car, ["other" => ["exterior" => $exteriorProperties]] ) ) );
オブジェクトタイプから配列タイプまでトップレベルのみをカバーする場合は、(array)
を使用してキャストできます。すべてのレベルを変換する必要がある場合-jsonはオブジェクト全体をエンコードしてから、その文字列を配列にデコードします。処理が完了したら、json_
関数を使用してデータをオブジェクトタイプに戻します。
これはまだ少し不格好です(おそらくあなたと同じくらい不格好です)条件付きアプローチ)。上記の利点は再帰にあります。データの深さが変更された場合、処理スクリプトを変更する必要はありません。実際にオブジェクトを使用する必要があるかどうかを自問してください。別のデータ型でコーディングが簡略化されている場合は、考え直してください。 / refactor。
Psは、stfu演算子(@
)をコードに絶対に記述しないでください。ほぼすべての実装で、この手法は回避可能であり(これはそのようなケースの1つです)、そのような構文のプロジェクトは、知識のある開発者によって低品質として分類/推定されます。
コメント
- ありがとう、良い評価。以前のプログラマーがオブジェクトをそのようにコーディングしていたため、残念ながらオブジェクト以外は選択できませんでした。
コメントを残す