72

仕事で大規模なリファクタリングが行われている最中に、関数からデータを返す方法として stdClass ***** を導入したいと考えており、私の決定を裏付ける非主観的な引数を見つけようとしています。

どちらか一方を使用するのが最適な状況はありますか??

配列の代わりに stdClass を使用すると、どのような利点がありますか??


関数は、単一の値を返すことができるように、小さくて具体的でなければならないと言う人もいます。stdClass を使用するという私の決定は、長期的には各プロセスに適切な値オブジェクトを見つけることを望んでいるため、一時的なものです。

4

7 に答える 7

63

通常のアプローチは

  • 固定ブランチを持つ定義済みデータ構造を返すときにオブジェクトを使用します。

     $person
       -> name = "John"
       -> surname = "Miller"
       -> address = "123 Fake St"
    
  • リストを返すときに配列を使用します。

      "John Miller"
      "Peter Miller"
      "Josh Swanson"
      "Harry Miller"
    
  • 構造化情報のリストを返すときは、オブジェクトの配列を使用します。

      $person[0]
        -> name = "John"
        -> surname = "Miller"
        -> address = "123 Fake St"
    
      $person[1]
        -> name = "Peter"
        -> surname = "Miller"
        -> address = "345 High St"
    

オブジェクトをアドレス指定するには常にキーが必要なため、オブジェクトはデータのリストを保持するのには適していません。配列は両方の機能を果たすことができます-任意のリストとデータ構造を保持します。

したがって、必要に応じて、最初と3番目の例のオブジェクトに対して連想配列を使用できます。それは本当にスタイルと好みの問題だと思います。

@Decezeは、オブジェクトをいつ使用するか(検証、型チェック、および将来のメソッド)について多くの良い点を示します。

于 2010-07-07T10:12:13.867 に答える
44

配列と同じ機能を実行するために使用stdClassすることは、私見ではあまり役に立ちません。実際の利点なしに、オブジェクトのオーバーヘッドを追加するだけです。また、多くの便利な配列関数(例)を見逃していますarray_intersect。少なくとも、型チェックを有効にするために独自のクラスを作成するか、オブジェクトを使用する価値があるようにオブジェクトにメソッドを追加する必要があります。

于 2010-07-07T10:13:19.920 に答える
18

関数呼び出しから複数の任意のデータ型を返すことが唯一の目的である限り、配列よりもstdClassを使用することの合理的な利点はないと思います。

技術的には複数の値をネイティブに返すことはできないため、PHPで使用可能な他のすべてのデータ型を保持できるコンテナーを使用する必要があります。これは、オブジェクトまたは配列のいずれかになります。

function fn1() { return array(1,2); }
function fn2() { return array('one' => 1, 'two' => 2); }
function fn3() { return (object) array(1,2); }
function fn4() { return (object) array('one' => 1, 'two' => 2); }

上記のすべてが機能します。配列はごくわずかな分数であり、入力する作業が少なくて済みます。また、一般的なstdClassとは対照的に、明確に定義された目的があります(これは少し意地悪ですが、そうではありません)。どちらも暗黙的なインターフェースしかないため、ドキュメントまたは関数本体を調べて、それらに何が含まれるかを知る必要があります。

とにかくオブジェクトを使用したい場合は、ArrayObjectまたはSplFixedArrayを使用できますが、それらのAPIを見ると、ランダムな複数の値を返すという単純なタスクのための機能が必要だと思いますか?私はそうは思わない。ただし、誤解しないでください。stdClassを使用する場合は、それを使用してください。それが何かを壊すようなものではありません。しかし、あなたも何も得られないでしょう。少なくともいくつかの利点を追加するために、このためにReturnValuesという名前の別のクラスを作成できます。

単純なタグ付けクラスである可能性があります

class ReturnValues {}

またはもっと機能的なもの

class ReturnValues implements Countable
{
    protected $values;
    public function __construct() { $this->values = func_get_args(); }
    public function __get($key) return $this->values[$key]; }
    public function count() { return count($this->values); }
}

確かに、それはあまり機能せず、そこから値を取得することは、暗黙のインターフェースを介して行われますが、少なくともクラスには、より明確に定義された責任があります。このクラスから拡張して、特定の操作用のReturnValueオブジェクトを作成し、それらに明示的なインターフェースを与えることができます。

class FooReturnValues extends ReturnValues
{
    public function getFoo() { return $this->values['foo']; }
    public function getBar() { return $this->values['foo']; }
}

これで、開発者はAPIを調べて、foo()が返す複数の値を知る必要があります。もちろん、複数の値を返す可能性のあるすべての操作に対して具体的なReturnValueクラスを作成する必要があると、すぐに面倒になる可能性があります。そして個人的には、これは当初の目的のために過剰に設計されていると思います。

とにかく、それが理にかなっていることを願っています。

于 2010-07-09T21:06:51.623 に答える
4

さて、3つの違いがあります:

  • 彼らにはアイデンティティがあります。これが、配列引数を渡すためのデフォルトが値による呼び出しであり、オブジェクトの場合は共有による呼び出しである理由です。
  • 意味的な違いがあります。オブジェクトを使用する場合、コードを読んだ人なら誰でも理解できるように、値はモデルのある種のエンティティを表し、配列はコレクションまたはマップとして機能するはずです
  • 最後に、リファクタリングが大幅に簡単になります。stdClass ではなく具象クラスを使用する場合は、別のクラスをインスタンス化するだけです。これにより、メソッドを追加することもできます。


グリッツback2dos

于 2010-07-07T13:04:50.797 に答える
2

私が見つけることができる唯一の客観的信任投票は次のとおりです。

json_decodeはデフォルトで stdClass を使用するため、ユーザーランドの人間は同様の状況で stdClass を使用する必要があります。

于 2014-04-24T16:14:22.887 に答える
1

コードをクリーンで文のように読みやすくする必要がある場合は、配列上のstdClassオブジェクトが便利です。たとえばgetProperties()、プロパティのセット、たとえば人に関するデータ(名前、年齢、性別)を返す関数を考えてみましょう。連想配列を返す場合getProperties()、返されたプロパティの1つを使用する場合は、次の2つの命令を記述します。

$data = getProperties();
echo $data['name'];

一方、getProperties()stdClassを返す場合は、1つの命令でそれを記述できます。

echo getProperties()->name;
于 2012-09-15T14:51:29.057 に答える