rfc:code_free_constructor

This is an old revision of the document!


PHP RFC: Code free constructor

Introduction

“Code free” constructor is constructor with only purpose to directly set object properties from received parameters and, optionally, call parent constructor.

They used for:

  • for DTO-classes declaration
  • developers, that believe it is good OOP-practice, use them everywhere
  • useful in some cases of inheritance

Unfortunately, php syntax enforces to write unnecessary boilerplate.

Proposal

Proposal is to add alternate syntax for “code free” constructors.

Current syntax:

class MotorCycle {
    public $vendor;
    public $cc;
    public $whells = 2;
 
    public function __construct($vendor, $cc) {
        $this->vendor = $vendor;
        $this->cc     = $cc;
    }
 
    //other methods
}
 
class MyCustomMotorCycle extends MotorCycle {
    public function __construct($cc, $whells) {
        parent::__construct("Custom", $cc);
     // $this->cc = $cc;  this statement will be added within proposed realisation
        $this->whells = $whells;
    }
}

Proposed syntax:

class MotorCycle($vendor, $cc){
    public $whells = 2;
 
    //other methods
};
 
class MyCustomMotorCycle($cc, $whells) extends MotorCycle("Custom", $cc){ };

By the way, current realization simply add “_ _construct” method into class via AST injection. Another words, code “($cc, $whells)” considered as zend_ast node “parameter_list” and accordingly processed by standart way. You can declare property type like you declare them inside standard method. Also you can declare defaults for parameters, use “...” notation (there is a nuance) and do everything else.

class MyCustomMotorCycle(int $cc, int $whells = 3, ...$otherParams) extends MotorCycle("Custom", $cc){ };

Restrictions

This syntax can't be used with anonymous classes because those classes instantiated at once they declared and same syntax is used for forwarding parameters directly into constructor.

Possible Issue

Child constructor will silently rewrite parent's properties with same name.

class Parent{
    public function __construct($prop){
        $this->prop = $prop * 2;
    }
}
class Child($prop) extends Parent($prop) {};
 
$child = new Child(5);
 
var_dump($child);
 
----------------
 
object(Child) {
    ["prop"] => 5 // instead expected 10
}

Backward Incompatible Changes

Do not know. Looks like no BI.

Proposed PHP Version(s)

PHP 8.x

RFC Impact

Not thinking so

Future Scope

Maybe simplified “destructuring declaration” for those class types? Not sure.

class A($first, $second) {};
$a = new A(1,2);
[$first, $second] = $a;

Implementation

Implemented via injecting generated “__construct”'s ast node into class statements list. So it will be compiled with all checks.

Draft implementation, need to be reviewed. https://github.com/php/php-src/compare/master...rjhdby:constructor

References

rfc/code_free_constructor.1548317332.txt.gz · Last modified: 2019/01/24 08:08 by rjhdby