Доступ к конкретному экземпляру класса

Я довольно новичок в ООП 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
}

Я видел людей, хранящих каждый экземпляр в глобальной переменной как массив объектов, но я также читал, что глобальные переменные считаются плохой практикой? И я нахожу их немного раздражающими, а работать с ними тоже.

Что было бы лучшим способом сделать это? желательно ООП подход?

0

Решение

Если вы создаете экземпляры динамически, то их хранение в массиве является общепринятым способом. Это не должно быть глобальным как бы то ни было.

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

То, как вы храните их для последующего использования, в значительной степени зависит от того, как вы их динамически создаете.

3

Другие решения

Вы можете создать свой собственный репозиторий; класс, единственная цель которого — создавать, отслеживать и восстанавливать эти автомобили. Это позволит вам избежать использования глобальной переменной. Конечно, тогда вам понадобится способ получить доступ к хранилищу. Вы всегда можете сделать его статическим, но тогда вы в некотором роде вернетесь к глобальному.

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

По вопросам рекламы [email protected]