【问题标题】:Accessing a specific instance of a class访问类的特定实例
【发布时间】:2014-09-19 13:58:06
【问题描述】:

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

【问题讨论】:

  • 什么名字?类的名称属性,或变量的名称(例如“ford”或“car1”?无论哪种方式,你正在尝试的似乎都是一个坏主意。请解释一下你为什么要这样做

标签: php oop instance


【解决方案1】:

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

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

您如何存储它们以供以后使用在很大程度上取决于您如何动态创建它们。

【讨论】:

  • 谢谢!我最终将它存储在一个数组中。
【解决方案2】:

您可以创建自己的存储库;一个唯一目的是创建、跟踪和恢复这些汽车的类。这将允许您避免使用全局变量。当然,您将需要一种访问存储库的方法。你总是可以让它成为静态的,但在某种程度上你基本上又回到了全局。

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

【讨论】:

    猜你喜欢
    • 2017-10-01
    • 2021-12-05
    • 2011-12-08
    • 2019-11-30
    • 2013-04-21
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    • 2022-01-25
    相关资源
    最近更新 更多