array( 'Param1', ..., 'ParamN' ) ), ... */ ) { # Создаем экзепляры наследуемых классов foreach( func_get_args() as $Class ) { $ClassName = ''; $ConstructorArguments = array(); if( is_array( $Class ) ) { $ClassName = array_shift( $Class ); $ConstructorArguments = array_shift( $Class ); } else $ClassName = $Class; # Через Reflection создаем экземпляр $Reflection = new ReflectionClass( $ClassName ); $this->ExtendsClasses[] = call_user_method_array( 'newInstance', $Reflection, &$ConstructorArguments ); } } /** * Перехватываем вызовы методов * @param string $Method * @param array $Arguments * @return mixed * @todo необходимо ввести правила, определяющие действия при ситуации, когда вызываемый метод находиться в двух и более наследуемых объектах */ private function __call( $Method, $Arguments ) { # Проходимся по всем классам, узнавая у кого есть вызываемый метод foreach( $this->ExtendsClasses as $Object ) { if( method_exists( $Object, $Method ) ) { # Делаем вызов метода return call_user_method_array( $Method, $Object, &$Arguments ); } } } /** * Перехватываем обращение к переменным класса * @param string $VariableName */ private function __get( $VariableName ) { # Проходимся по всем классам, узнавая у кого есть вызываемая переменная foreach( $this->ExtendsClasses as $Object ) { if( property_exists( $Object, $VariableName ) ) { return $Object->{$VariableName}; } } } /** * Прямое обращение к классам * @param string $ClassName * @return mixed */ public function getObject( $ClassName ) { foreach( $this->ExtendsClasses as $Object ) { if( get_class( $Object ) == $ClassName ) { return $Object; } } } } /** * Потестируем немного */ Class A { public $AClassProperty = 'AClassProperty'; static $String; function __construct( $String = '' ) { self::$String = $String; $String = 'AConstructByReference' . PHP_EOL; } function AFunction( $String = null ) { if( is_null( $String ) ) $String = self::$String; echo 'AFunction: ' . $String . PHP_EOL; } } Class B { function BFunction( $String ) { echo 'BFunction: ' . $String . PHP_EOL; $String = 'BFunction: BFunctionByReference'; } } $AString = 'StringA'; $BString = 'StringB'; $FirstClass = array( 'A', 'constructor_arguments' => array( &$AString ) ); $MultipleExtend = new MultipleExtendPattern( $FirstClass, 'B' ); echo PHP_EOL . 'Methods test: ' . PHP_EOL; $MultipleExtend->AFunction(); $MultipleExtend->AFunction( 'AString' ); $MultipleExtend->BFunction( &$BString ); echo PHP_EOL . 'By reference test: ' . PHP_EOL; echo $AString; echo $BString; echo PHP_EOL . PHP_EOL . 'Properties test: ' . PHP_EOL; echo $MultipleExtend->AClassProperty; echo PHP_EOL . PHP_EOL . 'ByClassTest: ' . PHP_EOL; echo $MultipleExtend->getObject( 'A' )->AClassProperty . PHP_EOL; echo $MultipleExtend->getObject( 'B' )->BFunction( $BString ); ?>