简体   繁体   中英

PHP classes - boilerplate or inherit?

Disclaimer: I'm a bit of a noob, only been doing PHP for under a year, and doing OO PHP less than that.

I'm writing several classes that all have some of the same functionality. Here's my boilerplate code for it:

class ClassName {

   // required constructor arguments
   private $arg1;

   // optional arguments in an array. $options array specifies their names
   // and required types. '' means any type.
   private $options = array('option1'=>'type', 'option2'=>'');
   private $option1 = 'default_value';
   private $option2 = 'default_value';

   /* getters and setters would go here if I wanted them */

   // this would probably change after debugging
   public function __toString() {
      return print_r(get_object_vars($this), true); 
   }

   public function __construct($arg1, array $options = array()) {
      // set all required args
      $this->arg1 = $arg1;
      // cycle through $options array, check they are allowed,
      // and check their type
      foreach ($options as $option => $value) {
         $type = $this->options[$option]; // no value = any type is OK
         if (array_key_exists($option, $this->options) 
                && (gettype($value) === $type || !$type)) {
            $this->$option = $value;
         }
      }
   }

   // methods go here
}

I'm using this format consistently: required parameters and then optional ones in an array, assigning all optional variables with a foreach loop, specifying the options and their types (the main distinction I care about is array vs. non-array) as a private variable.

The foreach loop that checks and assigns each of the optional parameters doesn't change. I can just copy and paste this to create new classes, but I also thought it might be better to do something like this to avoid duplicated code:

abstract class ParentClass {

   public function __toString() {
      return print_r(get_object_vars($this), true); 
   }

   protected function setOptions($options) {
      foreach ($options as $option => $value) {
         $type = $this->options[$option]; // no value = any type is OK
         if (array_key_exists($option, $this->options) 
                 && (gettype($value) === $type || !$type)) {
            $this->$option = $value;
         }
      }
   }
}

class ChildClass extends ParentClass{

   private $arg1;
   private $arg2;
   private $options = array('option1'=>'string', 'option2'=>'array');
   private $option1 = 'default_value';
   private $option2 = array('foo', 'bar');

   public function __construct($arg1, $arg2, $options = array()) {
      $this->arg1 = $arg1;
      $this->arg2 = $arg2;

      parent::setOptions($options);

   }
}

I haven't done much with inheritance yet. Is this a good use of it?

Thanks!

This would be a good use of inheritance, and it's always best practice to reduce duplicate code. DRY code is much less cumbersome to modify in the future when needs change or bugs arise.

Edit: By the way, you could also put all that construction logic in the parent class's constructor, then override it in the child class and call the parent constructor when you're done with class specific logic. For example:

abstract class ParentClass {
   public function __construct($options) {
      foreach ($options as $option => $value) {
         $type = $this->options[$option]; // no value = any type is OK
         if (array_key_exists($option, $this->options) 
         && (gettype($value) === $type || !$type)) {
            $this->$option = $value;
         }
      }
   }
   public function __toString() {
      return print_r(get_object_vars($this), true); 
   }
}

class ChildClass extends ParentClass{
   private $arg1;
   private $arg2;
   private $options = array('option1'=>'string', 'option2'=>'array');
   private $option1 = 'default_value';
   private $option2 = array('foo', 'bar');

   public function __construct($arg1, $arg2, $options = array()) {
      $this->arg1 = $arg1;
      $this->arg2 = $arg2;

      parent::__construct($options);
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM