PHP - 从内部替换对象

时间:2017-11-02 17:50:35

标签: php class oop object recursion

我想知道在PHP中做这样的事情是不好的做法(我假设是这样)?常识告诉我这可能导致UB,但我无法在手册或其他地方找到对此的引用。

<?php
    class A
    {
        public function __construct(){}
    }
    class B extends A
    {
        public function __construct()
        {
            global $d;
            $d = new C; // How wrong is it to replace the value of $d from inside B, like this?
            exit();
        }
    }
    class C extends A
    {
        public function __construct()
        {
            echo 'C';
        }
    }

    $d = new B;

输出:C

我想知道执行这样的代码所带来的风险(如果有的话),并且特别感谢指向这样做的手册的链接。

或者(因为这个简单的代码运行没有错误),这段代码是否有效,但只是被认为是一种不好的做法?

2 个答案:

答案 0 :(得分:0)

这在多个级别都是错误的。

  • 您不应在类中的任何位置使用全局状态(与全局变量和单例/注册表相关)。
  • 你不应该在类的方法中回应,特别是不要在构造函数中回显
  • 除非在“穷人调试”的背景下,否则不应该致电exit
  • 你不应该在构造函数中创建另一个类的新实例,因为它变得非常难以测试和调试
  • 您不应滥用extends关键字,因为它用于创建基类的专用子类型

答案 1 :(得分:-1)

如果您期望变量$d将包含C类实例,那么您就错了。 要查找,请使用exit()$d删除代码末尾的print_r()并转储var_dump()

// your code here without the exit()
echo "\n";
print_r($d);

以下是整个输出:

C
B Object
(
)

这是一个惊喜吗? 实际上,它不应该是。

在B类的构造函数中修改$d是没有意义的,因为当构造函数返回时, 任何$d中的值都将被新的B类实例覆盖。

没有任何关于这是未定义的行为。 只是毫无意义,因为它什么都没有。