Возможно ли что-то вроде следующего в PHP?
$blah = 'foo1';
class foo2 extends $blah {
//...
}
class foo1 {
//...
}
Это дает ошибку.
Я хочу динамически установить $ blah, чтобы я мог расширить любой класс, который я хочу.
Редактировать: Причиной желания сделать это, потому что я хотел использовать функцию из другого класса в связанном классе. В конце концов это было бы что-то вроде:
Final extends foo1 extends foo2 extends foo3 extends foo4 extends parent { ... }
В конце я решил создать экземпляр другого класса в классе и использовать его. Не лучший вариант, потому что они оба из двух классов, но это будет использоваться не так часто, так что пока это будет работать.
Вы предполагаете, что здесь 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()
решение … удачи с этим … 🙂
Я знаю, что этот вопрос задавали давно, но ответ относительно прост.
Предполагая, что вы хотите расширить класс foo, если класс foo существует, или класс bar, если его нет, вы должны использовать:
if(!class_exists('foo')) {
class foo extends bar {
function __construct() {
parent::__construct();
}
}
}
class myclass extends foo{
//YOUR CLASS HERE
}
Я предполагаю, что это для простоты обслуживания, верно? Продление класса во время выполнения действительно довольно безумно.
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
поэтому ответ на вопрос «возможны ли расширения класса переменных?» нет.
С помощью Перегрузка 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 модуль за предварительная выборка данных из кеша.
ты должен был попробовать $$
$blah = 'foo1';
class foo2 extends $$blah {
//...
}
class foo1 {
//...
}