访问类的特定实例

时间:2014-09-19 13:58:06

标签: php oop instance

我对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方法?

2 个答案:

答案 0 :(得分:3)

如果要动态创建实例,则将它们存储在数组中是一种普遍接受的方式。但它不一定是全球性的。

$cars = array();

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

$ford = $cars['ford'];

这个过程可以通过以下函数抽象:

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');

如何存储它们供以后使用,取决于你如何动态创建它们。

答案 1 :(得分: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' );