There may be good reasons for extending a third-party "final" class, which leads to more readable / supported code than completely duplicating it or creating some confusing work. And, of course, it’s preferable to change the source code of third-party developers and delete the “final” keyword.
PHP provides a “Component” extension to perform such a feat on those rare occasions when it is truly the best option. The following is an example showing how a child class can be defined as a "tag", which can then be used to dynamically extend the final parent class:
<?php declare(strict_types=1); /* * Final class would normally prevent extending. */ final class ParentC { public $parentvar; public $secondvar; function __construct() { echo( "\r\n<br/>".$this->parentvar = 'set by '.get_class().'->parentconstruct' ); } function parentf() { echo( "\r\n<br/>".get_class().'->parentf >> '.$this->parentvar ); } } /* * Extended class members. */ trait ChildC /* extends ParentC */ { function __construct() { // Call parent constructor. parent::__construct(); // Access an inherited property set by parent constructor. echo( "\r\n<br/>".get_class().'->overridden_constructor >> '.$this->parentvar ); } function parentf() { // Call overridden parent method. parent::parentf(); // Access an inherited property set by constructor. echo( "\r\n<br/>".get_class().'->overridden_parentf >> '.$this->parentvar ); } function dynamicf( $parm = null ) { // Populate a parent class property. $this->secondvar = empty( $parm ) ? 'set by '.get_class().'->dynamicf' : $parm; // Access an inherited property set by parent constructor. echo( "\r\n<br/>".get_class().'->dynamicf >> '.$this->parentvar ); } } /* * Register the dynamic child class "ChildC", which is * derived by extending "ParentC" with members supplied as "ChildC" trait. */ $definition = new \Componere\Definition( 'ChildC', ParentC::class ); $definition->addTrait( 'ChildC' ); $definition->register(); /* * Instantiate the dynamic child class, * and access its own and inherited members. */ $dyno = new ChildC; $dyno->parentf(); $dyno->dynamicf( 'myvalue '); // Our object is also recognized as instance of parent! var_dump( $dyno instanceof ChildC, $dyno instanceof ParentC, is_a( $dyno, 'ParentC') ); var_dump( $dyno ); ?>
Andy schmidt
source share