Я довольно новичок в ООП 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
}
Я видел людей, хранящих каждый экземпляр в глобальной переменной как массив объектов, но я также читал, что глобальные переменные считаются плохой практикой? И я нахожу их немного раздражающими, а работать с ними тоже.
Что было бы лучшим способом сделать это? желательно ООП подход?
Если вы создаете экземпляры динамически, то их хранение в массиве является общепринятым способом. Это не должно быть глобальным как бы то ни было.
$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');
То, как вы храните их для последующего использования, в значительной степени зависит от того, как вы их динамически создаете.
Вы можете создать свой собственный репозиторий; класс, единственная цель которого — создавать, отслеживать и восстанавливать эти автомобили. Это позволит вам избежать использования глобальной переменной. Конечно, тогда вам понадобится способ получить доступ к хранилищу. Вы всегда можете сделать его статическим, но тогда вы в некотором роде вернетесь к глобальному.
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' );