应该何时将对象作为参数传递vs实例化?

时间:2014-10-21 06:36:47

标签: php instantiation

我很好奇有关将对象实例作为参数传递给同一个类中的另一个函数而不是在新函数中创建该对象的另一个实例的最佳实践和任何性能或其他注意事项。这是一个简单的例子:

选项1:将实习生和实习生控制的两个实例传递给其他职能

protected function startTraining($traineeID) {
    $traineeController = new TraineeController();
    $trainee = $traineeController->findTrainee($traineeID);
    $this->initializeTraining($trainee, $traineeController);
    $this->doSomeOtherStuffWithTrainee($trainee, $traineeController);
    return Redirect::back()->with('trainee', $trainee);
}

protected function initializeTraining($trainee, $traineeController) {
    $trainee->blah1 = 'red';
    $trainee->blah2 = 'blue';
    $propertiesToUpdate = [
        'blah1' => $trainee->blah1,
        'blah2' => $trainee->blah2
    ];
    $traineeController->updateTrainee($trainee->traineeID, $propertiesToUpdate);
}

选项2:仅限$ trainee,每次实例化一个新的TaineeController

protected function startTraining($traineeID) {
    $traineeController = new TraineeController();
    $trainee = $traineeController->findTrainee($traineeID);
    $this->initializeTraining($trainee);
    $this->doSomeOtherStuffWithTrainee($trainee);
    return Redirect::back()->with('trainee', $trainee);
}

protected function initializeTraining($trainee) {
    $trainee->blah1 = 'red';
    $trainee->blah2 = 'blue';
    $propertiesToUpdate = [
        'blah1' => $trainee->blah1,
        'blah2' => $trainee->blah2
    ];
    $traineeController = new TraineeController();
    $traineeController->updateTrainee($trainee->traineeID, $propertiesToUpdate);
}

在上面我需要每次都将$trainee传递给所有函数,而不是从$traineeID创建一个新的受训者,因为在“培训”过程中其他一些东西会在幕后进行,否则在将相关数据保存到数据库之前丢失。但是,TraineeController不需要这个 - 我可以将它作为参数传递,也可以根据需要实例化一个新的TraineeController。哪个是更好的选择?

我看到this question relating to C#,其中接受的答案是传递整个对象通常更有效并且实例化另一个对象,因为您通过引用传递。这适用于PHP吗?即使用&

引用所需函数来传递整个对象的最有效方法

1 个答案:

答案 0 :(得分:1)

将对象作为引用传递没有任何问题,但请注意,php期望您的函数参数需要期望引用而不是仅通过引用传递变量(php docs)。如果不遵守这个问题,php 5.4.0甚至会引发致命错误:

右:

protected function initializeTraining($trainee, &$traineeController) {}
$this->initializeTraining($trainee, $traineeController);  

错误:

protected function initializeTraining($trainee, $traineeController) {}
$this->initializeTraining($trainee, &$traineeController);  

通过引用传递对象在大多数情况下比再次启动对象具有更好的性能,但如果对象具有自己的属性,则通过引用传递可能会变得棘手:

class TraineeController {

  $fooCalled = false;

  function foo(){ $this->fooCalled = true; }

  function isFooCalled(){ return $this->fooCalled; }
}

$traineeController = new TraineeController();
$traineeController->foo();

//&$traineeController->isFooCalled() will be different from
//new TraineeController()->isFooCalled().