This is an old revision of the document!
PHP RFC: Code free constructor
- Version: 0.1
- Date: 2019-01-14
- Author: Andrey Gromov, andrewgrom@rambler.ru, rjhdby@php.net
- Proposed version: PHP 8
- Status: draft
- First Published at: https://wiki.php.net/rfc/code_free_constructor
- ML thread: -
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