В PHP есть что-то вроде следующего?
$blah = 'foo1'; class foo2 extends $blah { //... } class foo1 { //... }
Это дает ошибку.
Я хочу динамически установить $ blah, чтобы я мог расширить любой класс, который я хочу.
Изменить: причина для этого, потому что я хотел использовать функцию из другого класса в связанном классе. В конце концов, это было бы примерно так:
Final extends foo1 extends foo2 extends foo3 extends foo4 extends parent { ... }
В конце концов я решил создать экземпляр другого класса в классе и использовать его. Не лучшие варианты, потому что они оба у вас 2 из тех же классов, но это не будет использоваться так часто, так что это будет работать пока.
Вы предполагаете, что php выполняется сверху вниз, но это не совсем так:
<?php foo(); # works function foo(){ print "bar"; }
<?php foo(); #dies if( $i == 1 ) { function foo(){ print "bar"; } }
<?php $i = 1; if( $i == 1 ) { function foo(){ print "bar"; } } foo(); #works
Теперь, хотя вы можете условно создавать классы:
<?php class A { } class B { } if( false ){ class C extends B { public static function bar(){ print "baz"; } } } C::bar(); # dies
Вы не можете создать экземпляр во время выполнения из переменной:
<?php class A { } class B { } $x = 'B'; if( false ){ class C extends $x { public static function bar(){ print "baz"; } } } C::bar(); ---> Parse error: syntax error, unexpected T_VARIABLE, expecting T_STRING in /tmp/eg.php on line 7
Есть способ сделать это с Eval, но вы действительно не хотите туда ехать:
<?php class A { } class B { } $x = 'B'; if( true ){ $code =<<<EOF class C extends $x { public static function bar(){ print "baz"; } } EOF; eval( $code ); } C::bar(); $o = new C; if ( $o instanceof $x ) { print "WIN!\n"; } --->barWIN!
Однако здесь есть более важный вопрос:
Почему, черт возьми, вы хотите расширить класс во время выполнения
Любой, кто использует ваш код, захочет удержать вас и выбить вас за это.
(В качестве альтернативы, если вы используете взбивание, сделайте этот трюк)
Я не понимаю, как это было бы особенно полезно, но чтобы ответить на ваш вопрос … нет. Нет никакого способа динамически сделать это, потому что сгенерированный класс должен быть создан до того, как переменная будет оценена (если это имеет смысл).
Проще говоря: класс должен существовать до того, как код будет правильно выполнен.
Если у вас не слишком много значений для $ blah, вы можете расширить их в другом файле, а затем require_once "classes/foo_$blah.php"
В противном случае вы застряли с решением eval()
… удачи с этим … 🙂
Я предполагаю, что это для удобства обслуживания, не так ли? Расширение класса во время выполнения действительно довольно сумасшедшее.
class SuperClassOne { /* code */ } class SuperClassTwo { /* code */ } class IntermediateClass extends SuperClassOne { /* empty! */ } class DescendantClassFoo extends IntermediateClass{ } class DescendantClassBar extends IntermediateClass{ } class DescendantClassBaz extends IntermediateClass{ }
Затем, когда вы хотите изменить все классы DescendantClass*
, вам просто нужно изменить то, что расширяет IntermediateClass:
class IntermediateClass extends SuperClassTwo { }
Я проверил что-то с определениями и лаем:
<?php define("INHERIT",A); class A{ public function bark(){ return "I'm A"; } } class B{ public function bark(){ return "I'm B"; } } class C extends INHERIT{} //main? $dog = new C(); echo $dog->bark(); ?>
выход:
Неустранимая ошибка: класс «INHERIT» не найден в D: \ sites \ inherit.php в строке 15
так что ответ на вопрос: «Возможно ли расширение переменных классов?» нет.
Я знаю, что этот вопрос был задан давно, но ответ относительно прост.
Предполагая, что вы хотите расширить класс foo, если класс foo существует, или панель классов, если это не так, вы должны использовать:
if(!class_exists('foo')) { class foo extends bar { function __construct() { parent::__construct(); } } } class myclass extends foo{ //YOUR CLASS HERE }
Используя перегрузку PHP, вы можете в определенной степени выполнить это.
class variable_class { public $orginalBaseClass; public $orginalArgs; public function __construct() { // Get constructor parameters. $this->orginalArgs = func_get_args(); // Get class name from args or 3rd party source. $classname = 'stdClass'; // Pass along args to new class. $this->orginalBaseClass = new $classname($this->orginalArgs); } public function __call($name, $arguments) { // Pass all method calls to the orginalBaseClass. return call_user_func_array(array($this->orginalBaseClass, $name), $arguments); } }
Я использую этот шаблон внутри модуля Drupal для предварительной выборки данных из кеша .
<?php class AAA { function go() { echo 'WORKS!'; } } $a = 'AAA'; use AAA as Eclass; class BBB extends EClass { } BBB::go(); ?>
вы должны были попробовать $$
$blah = 'foo1'; class foo2 extends $$blah { //... } class foo1 { //... }