Tell me how to pass the values ​​from the constructor to the generated objects, or when creating a new instance, you could hammer values ​​into the constructor, Chet is completely confused

class carFactory { public function __construct() { } public static function build ($type = '') { if($type == '') { throw new Exception('Invalid Car Type.'); } else { $className = 'car_'.ucfirst($type); if(class_exists($className)) { return new $className(); } else { throw new Exception('Car type not found.'); } } } } class car_Sedan { public function __construct() { echo "Creating Sedan"; } } class car_Suv { public function __construct() { echo "Creating SUV"; } } 

    2 answers 2

     <?php class carFactory { public function __construct() { } public static function build ($type = '', $options = []) { if($type == '') { throw new Exception('Invalid Car Type.'); } else { $className = 'car_'.ucfirst($type); if(class_exists($className)) { return new $className($options); } else { throw new Exception('Car type not found.'); } } } } class Car { public function __construct($options = []) { var_dump($options); } } class car_Sedan extends Car { public function __construct($options) { parent::__construct($options); echo "Creating Sedan"; } } class car_Suv extends Car { public function __construct($options) { parent::__construct($options); echo "Creating SUV"; } } carFactory::build('Suv', ['wheels' => 5]); echo PHP_EOL; carFactory::build('Sedan', ['wheels' => 4]); /** array(1) { ["wheels"]=> int(5) } Creating SUV array(1) { ["wheels"]=> int(4) } Creating Sedan **/ 
    • one
      Instead of an array, it is better to use an implementation interface class - Gedweb
    • and then what's the point of the constructor in carFactory - ddeadlink

    Let me give you another example for the case when an arbitrary number of arguments must be passed to the constructor of a factory product, and different products may have different designer signatures. For example, if a class appears like car_Sedan_With_Custom_Engine , with a constructor:

     class car_Sedan_With_Custom_Engine extends car_Sedan { /** * @var EngineInterface */ private $engine; public function __construct(array $options = [], EngineInterface $engine = null) { parent::__construct($options); if ($engine) { $this->engine = $engine; } } //...методы классы } 

    Where the object that implements the EngineInterface is also passed to the constructor (for example, to apply the Strategy pattern). Then you can use the Reflection API reflection mechanism (this approach cannot be recommended for all occasions, it has certain drawbacks, but it works for a number of applications) and use the ReflectionClass::newInstanceArgs method. Then you can rewrite the factory method, thus:

     public static function build ($type = '', $args = []) { if($type == '') { throw new Exception('Invalid Car Type.'); } else { $className = 'car_'.ucfirst($type); if(class_exists($className)) { $reflect = new ReflectionClass($class); $object = $reflect->newInstanceArgs($args); return $object; } else { throw new Exception('Car type not found.'); } } } 

    Then the client code to create an instance of car_Sedan will look like this:

     $sedan = carFactory::build('car_Sedan', [$options]); 

    And to create car_Sedan_With_Custom_Engine :

     $customizedSedan = carFactory::build( 'car_Sedan_With_Custom_Engine', [$options, new CustomEngine()] );