代码之家  ›  专栏  ›  技术社区  ›  Aiden Bell

PHP和运行时子类化/对象重分类

  •  1
  • Aiden Bell  · 技术社区  · 14 年前

    classA 实例的子类 classX ... 在构建时(或其他时候),我希望它加载另一个类 classB 它也是 并用 原地。有点像一个工厂,但它可以透明地替换自己。如果需要,我可以包起来 B类 具有 甲级

    目前我正在使用 classA::__call() 模仿MRO的魔法,但似乎很不雅观。这需要对调用方透明地完成 classA/B 已将自己替换为 施工后(或其他地方)。

    我知道PHP在做这样的事情时会有点单薄。。。我怀疑我们做不到,但这对我的情况很方便。

    另外,5.3,但理想情况下(恶心)5.2/x

    2 回复  |  直到 14 年前
        1
  •  1
  •   bob-the-destroyer    14 年前

    好吧,我对这个问题很感兴趣,因为我已经到了我想发现PHP的确切限制的地步,包括像这样的小黑客。希望我能在这么晚的时候,喝几杯啤酒。因为丑陋的黑客行为,我真的希望被否决。

    $this = $that . 在构造对象时,也不能将当前试图生成的全局变量更改为对象,并且尝试这样做将被忽略。正如查尔斯早些时候所说,这是不合理的。不是和 clone ,不是 serialize() __construct() .

    因此,如果您不合理地希望$a首先成为类a的对象,然后将中间创建转换为类B,请尝试以下伪方法:您必须连续调用类a的\uu构造两次。第一次办理甲级施工。第二次完成对象转换为类B。A类负责前半部分施工,B类负责后半部分施工:

    class A {
    
        function __construct() {
            $args = func_get_args();  // just to tell us the first round of __construct already occured
            if (array_key_exists(0, $args) AND $args[0]) {
                $GLOBALS['a'] = new B($GLOBALS['a']);
                // stop because "reconstruction" has stopped.  Nothing else you can do to $a in this scope.
                $this->aprop2 = "yay";
                // Seriously, stop.  Don't bother putting more code at this point, you're wasting your time.  Consider $a 'converted and returned' already.
                }
            // build on an object of class a here
            }
        }
    
    class B {
    
        function __construct($var) {
            // maybe you'd like to do something with old $a?  If so, here's $var for you
            // continue constructing where A left off.
            }
    
        }
    
    
    $a = new A(); // object of class A
    $a->__construct(true);  // object of class B
    
    

    编辑: $a = new A(); $a = new B($a); www.ibm.com 文章解释了工厂的概念以及如何在PHP中应用它们。可能在概念上,您需要一个静态类,它的行为类似于cd换碟机,这就是 Return by Reference -在任何范围内使用对对象的变量引用-和 Variable Objects (参考:midir在该页上的注释)-动态设置或使用对象-非常方便。

        2
  •  1
  •   Charles    14 年前

    这在PHP中是不可能的。。。

    不做傻事。

    如果 对象的实例是一个引用,这些引用可以在中找到 $GLOBALS ,并且对象知道这些实例中的每一个都调用了什么,您知道吗 能够

    __call 魔术可能是实现你的目标最不疯狂的方式。

    runkit ,这将允许您从类中添加和删除方法。但是,它是一个PECL扩展,甚至可能无法正常工作。。。