2014-09-19 199 views
0

對於OOP PHP來說,這是相當新穎的,所以我試圖學習。訪問某個類的特定實例

我有一個名爲「Awesome_Car」我確定,像這樣

class Awesome_Car { 

    public $attributes; 
    public $name; 

    function __construct($name, $atts) { 
     $this->name = $name; 
     $this->attributes = $atts; 
    } 

} // end of class 

類和我的代碼的某個地方實例化這個類x次:

$car1 = new Awesome_Car('ford', array('color'=>'blue', 'seats' => 6)); 
$car2 = new Awesome_Car('bmw', array('color'=>'green', 'seats' => 5)); 

現在我想提出一個正常的函數,允許我通過名稱獲取 - 和操作 - 該類的特定實例。像

function get_specific_car_instance($name) { 

    //some code that retrives a specific instance by name 

    //do stuff with instance 

    //return instance 
} 

東西,我看到人們存儲的每個實例在一個全局變量作爲對象的數組,但我也看到了全局變量被認爲是不好的做法?而且我確實發現他們也有點討厭工作。

這樣做會更好嗎?最好是OOP方法?

+1

什麼名字?該類的名稱屬性或變量的名稱(例如「ford」或「car1」)?無論哪種方式,你正在嘗試的似乎是一個糟糕的主意。請注意解釋你爲什麼要這樣做 – Steve 2014-09-19 14:07:04

回答

3

如果您要動態創建實例,那麼將它們存儲在數組中是普遍接受的方式。但它不一定是全球性的。

​​

這ofcourse可以通過函數抽象,如:

function get_car(&$cars, $name) { 
    if (! isset($cars[$name])) { 
     throw new \InvalidArgumentException('Car not found'); 
    } 

    return $cars[$name]; 
} 

$ford = get_car($cars, 'ford'); 

或者更高級的容器類,如:

// Requires doctrine/common 
use Doctrine\Common\Collections\ArrayCollection; 

$cars = new ArrayCollection(); 

$cars->set('ford', new Awesome_Car('ford', array('color'=>'blue', 'seats' => 6))); 
$cars->set('bmw', new Awesome_Car('bmw', array('color'=>'green', 'seats' => 5))); 

$ford = $cars->get('ford'); 

你如何儲存以備日後使用取決於相當有點關於你如何動態創建它們。

+0

謝謝!我結束了把它存儲在一個數組中。 – 2014-09-21 14:21:00

0

您可以創建自己的存儲庫;一個只有創建,跟蹤和恢復這些汽車的課程。這將允許您避免使用全局變量。當然,你需要一種方式來訪問存儲庫。你總是可以使它成爲靜態的,但是你基本上以某種方式回到了全局。

class CarRepository { 

    private $cars = array(); 

    public function makeCar($name, $atts) { 
     $this->cars[] = new Awesome_Car($name, $atts); 
    } 

    public function findByName($name) { 
     foreach($this->cars as $car) { 
     if($car->name == $name) { 
      return $car; 
     } 
     } 
    } 
} 

// you'll need a way to obtain the repository to find cars; but it means you can have different repositories in your code 
$repo = new CarRepository; 
$repo->makeCar('ford', array('color'=>'blue', 'seats' => 6)); 
$repo->findByName('ford'); 

或完全靜態的版本:

class CarRepository { 

    private static $cars = array(); 

    public static function makeCar($name, $atts) { 
     self::$cars[] = new Awesome_Car($name, $atts); 
    } 

    public static function findByName($name) { 
     foreach(self::$cars as $car) { 
     if($car->name == $name) { 
      return $car; 
     } 
     } 
    } 
} 

// you can access this from ANYWHERE, but you can only ever have a single repository 
CarRepository::makeCar('ford', array('color'=>'blue', 'seats' => 6)); 
CarRepository::findByName('ford');