PHP 中的变量变量类扩展——可能吗?

发布于 2024-07-08 20:31:38 字数 439 浏览 13 评论 0原文

PHP 中可能有类似以下内容吗?

$blah = 'foo1';

class foo2 extends $blah {
    //...
}

class foo1 {
    //...
}

这会产生错误。

我想动态设置 $blah 这样我就可以扩展我想要的任何类。

编辑:想要这样做的原因是因为我想使用相关类中另一个类的函数。 最后它会是这样的:

Final extends foo1 extends foo2 extends foo3 extends foo4 extends parent { ... }

最后我决定实例化类中的另一个类并使用它。 这不是最好的选择,因为它们都是同一类的两个,但这不会经常使用,所以它现在可以使用。

Is something like the following possible in PHP?

$blah = 'foo1';

class foo2 extends $blah {
    //...
}

class foo1 {
    //...
}

This gives an error.

I want to dynamically set $blah so I can extend whatever class I want.

Edit: The reason for wanting to do this because I wanted to use a function out of another class in a related class. In the end it would have been something like:

Final extends foo1 extends foo2 extends foo3 extends foo4 extends parent { ... }

In the end I decided to instantiate the other class within the class and use it. Not the best options because they both you 2 of the same classes, but this won't be used that often, so it will work for now.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

韶华倾负 2024-07-15 20:31:38

你假设这里 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!

然而,这里有一个更重要的问题:

为什么你想要

任何使用你的代码的人都会想压制你并鞭打你。

(或者,如果你喜欢鞭打,可以使用 eval 技巧)

You're assuming here php executes top to bottom, but it doesn't quite work like that:

<?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

Now, although you can conditionally create classes:

<?php

class A { }
class B { }
if( false ){ 
  class C extends B { 
    public static function bar(){
      print "baz"; 
    }
  }
}
C::bar(); # dies

You cant instantiate one at runtime from a variable:

<?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

There is a way to do it with Eval, but you really don't want to go there:

<?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!

However, there is a more important question here:

Why the hell would you want to extend a different class at runtime

Anybody using your code will want to hold you down and whip you for that.

( Alternatively, if you're into whipping, do that eval trick )

一杯敬自由 2024-07-15 20:31:38

我知道这个问题很久以前就被问过,但答案相对简单。

假设您想在 foo 类存在时扩展 foo 类,如果不存在则扩展 bar 类,您可以使用:

if(!class_exists('foo')) {
    class foo extends bar {
        function __construct() {
            parent::__construct();
        }
    }
}

class myclass extends foo{
    //YOUR CLASS HERE
}

I know this question was asked a long time ago, but the answer is relatively simple.

Assuming you want to extend class foo if class foo exists, or class bar if it doesn't, you'd use:

if(!class_exists('foo')) {
    class foo extends bar {
        function __construct() {
            parent::__construct();
        }
    }
}

class myclass extends foo{
    //YOUR CLASS HERE
}
蘑菇王子 2024-07-15 20:31:38

使用 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 模块 中使用此模式 从缓存中预取数据

Using PHP overloading you can accomplish this to a certain extent.

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);
    }
}

I'm using this pattern inside a Drupal module for prefetching data from the cache.

假面具 2024-07-15 20:31:38

我不认为这会特别有用,但要回答你的问题......不。 无法动态地执行此操作,因为必须在评估变量之前实例化生成的类(如果这有意义)。

简单来说:类必须存在,代码才能正确执行。

I don't see how this would be particularly useful, but to answer your question... no. There's no way to dynamically do that because the generated class has to be instantiated before the variable is evaluated (if that makes sense).

To put it simply: The class must exist before the code can be properly executed.

烟若柳尘 2024-07-15 20:31:38

如果 $blah 没有太多值,您可以在不同的文件中扩展每个值,然后 require_once "classes/foo_$blah.php"

否则,您将陷入 eval() 解决方案...祝你好运...:)

If you don't have too many values for $blah, you could extend each one in a different file then require_once "classes/foo_$blah.php"

Otherwise, you're stuck with the eval() solution... good luck with that... :)

城歌 2024-07-15 20:31:38

我认为这是为了便于维护,对吗? 在运行时扩展一个类确实非常疯狂。

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 { }

I assume that this is for ease-of-maintenance, right? Extending a class at run time really is pretty crazy.

class SuperClassOne { /* code */ }
class SuperClassTwo { /* code */ }

class IntermediateClass extends SuperClassOne { /* empty! */ }

class DescendantClassFoo extends IntermediateClass{ }
class DescendantClassBar extends IntermediateClass{ }
class DescendantClassBaz extends IntermediateClass{ }

Then, when you want to change all your DescendantClass* classes, you just have to change what the IntermediateClass extends:

class IntermediateClass extends SuperClassTwo { }
国产ˉ祖宗 2024-07-15 20:31:38

我用定义和吠叫测试了一些东西:

<?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 行

因此“变量类扩展是否可能?”的答案 没有。

I tested something with defines and barking:

<?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();
?>

the output is:

Fatal error: Class 'INHERIT' not found
in D:\sites\inherit.php on line 15

so the answer for "are variable class extensions possible?" is: No.

时光沙漏 2024-07-15 20:31:38

你应该尝试过$$

$blah = 'foo1';
class foo2 extends $blah {
    //...
}

class foo1 {
    //...
}

you should have tried $$

$blah = 'foo1';
class foo2 extends $blah {
    //...
}

class foo1 {
    //...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文