2014-09-19 125 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');