2011-03-06 2 views
0

例を考えてみましょう:(どのように)オブジェクト参照を使用する必要がありますか?

会社のスタッフを扱うアプリケーションライブラリ。スタッフの詳細はCSVファイルに保存されています(例として使用されているため、これを判断しないでください)。スタッフ情報を扱う
クラスは(コードは非常にちょうどあなたの写真を与えるために単純化)されている:

class Staff { 
    /* array containing all Staff_Emplyee objects naturally (number) indexed */ 
    public $employees; 
    /* array containing all Staff_Employee objects $name indexed */ 
    public $employees_names; 
    /* array containing all Staff_Team objects naturally indexed */ 
    public $teams; 
    /* array containing all Staff_Team objects $name indexed */ 
    public $teams_names; 

    /* parses CSV file 
    * creates new Staff_Employee objects 
    * creates new Staff_Team objects 
    * adds references to each Staff_Employee::$managers and Staff_Employee::$team 
    * adds references to Staff_Team::$managers and Staff_Team::$staff */ 
    public __construct(); 

    /* returns a single Staff_Employee object */ 
    public get_employee($name) {}; 

    /* returns a single Staff_Team object */ 
    public get_team($name) {}; 
} 


class Staff_Employee { 
    /* string */ 
    public $name; 
    /* array containing all Employee's managers as Staff_Employee objects */ 
    public $managers; 
    /* Staff_Team object of the team the Employee is in */ 
    public $team; 
} 

class Staff_Team { 
    /* string */ 
    public $name; 
    /* array of all managers in the team (Staff_Employee objects) */ 
    public $managers; 
    /* array of all non-managers in the team (Staff_Employee objects) */ 
    public $staff; 
} 

、現時点でのアプリケーションで使用される参照がありません。すべてのオブジェクト変数は値渡しです。私はこれに潜在的にオーバーヘッドがあると思った。だから、一度、すべての従業員とチームのオブジェクトは、私は単に例えば、参照するものにすべてのコールを変更しようとしている。:

$team1->managers[] = &$employee1; 
$employee0->managers[] = &$employee1; 

しかし、私には驚くべきことであった。この一瞬の増加メモリ使用量に作成されます。私が使っている例はわずか200人分のスタッフしかいませんが、企業に対処しなければならないときには、これは数千またはそれ以上になる可能性があり、メモリ使用量はさらに増えると思います。

私はこの例を考えていたとき、私はこのような何かを行うことができますどこORMを模倣しようとした:

$team->staff[n]->managers[n]->name; // infinite chaining? 

理想的には「適切」(?初期)のオブジェクトのみをStaff::$employeesStaff::$teamsに格納されますしたがって、Staff::$teams_names['Team Name']Staff::$teams[n]への参照になります。同様にStaff_Team::$managersは、Staff::$employeesなどへの参照配列になります。
しかし、私が言及したように - 参照を使用し始めるとすぐにメモリ使用量が増加します。

質問:
これをどうすれば処理できますか?
参照渡しを使用し、メモリ使用について心配する必要はありませんか、値渡しを使用する必要がありますか?
この場合、どちらが優れていますか?その理由は何ですか?

注1:私は(私は)値渡しと参照渡しの違いを理解していると思います。私はこの例ではどちらが良いか尋ねているだけです。
注2:作成後、Staff_Employeeオブジェクトに何らかの操作が行われることがあります。おそらく非常に最小限。

+0

ええ、私はあなたが持っているものを再現しようとしましたが、オブジェクトが配列にどのように追加されてもメモリ使用量が増加していることに気付かなかった... PHP 5は実際にはデフォルトで参照によってオブジェクトを渡します。この場合にはあまり効果がありません。 – Sergey

答えて

1

短い答え:(。紛らわしいことに、参照渡し、他の言語でと呼ばれている)

「値渡し」、アンパサンドを使用しないでください長い答え:私はいくつかのコード例を考えますほとんどの説明になります。

$a = new stdclass(); 
$b = $a; 
$c = &$a; 
$a->field = 'asdf'; 
echo '$b->field = ' . $b->field . "\n"; // $b->field = asdf 
echo '$c->field = ' . $c->field . "\n"; // $c->field = asdf 

あなたは、単にオブジェクトのフィールドに割り当てるのであれば、違いはありません。アンパサンドは、が変数自体を上書きする場合にのみ違いがあります

$a = new stdclass(); 
$b = $a; 
$c = &$a; 
$a = 2; 
echo 'is_object($b) = ' . is_object($b) . "\n"; // is_object($b) = 1 
echo 'is_object($c) = ' . is_object($c) . "\n"; // is_object($c) = 0 

しかし、一般的に、行動のその種は悪いジュジュ(あなたは、たとえば、関数から複数の値を返すようにしようとしている場合にのみ有効です。あなたはまたのためlist()を使用することができます。)

関連する問題