【问题标题】:PHP - Replacing an object from inside itselfPHP - 从内部替换对象
【发布时间】:2018-04-15 08:26:37
【问题描述】:

我想知道在 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

我想知道执行这样的代码所带来的风险(如果有的话),并且特别感谢一个关于执行这样的事情的手册的链接。

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

【问题讨论】:

  • 类和对象不是为此目的而制作的。如果您在不同的变量中创建超过 1 个,它将不起作用......您可以将它用于您自己的代码,但您不应该这样做。制作了一些if 的帮助
  • @GrumpyCrouton 我的意思是将我的问题更多地指向从内部替换对象的行为(正如标题所暗示的那样),而不仅仅是它使用 global 的事实。对不起,如果我不清楚。
  • @user6003859 我知道,我并没有真正回答你的问题(否则我会发布答案),我在评论全局变量的使用。我认为这与您有关,因为您担心不良的编码实践:) 如果您担心任何不良编码实践,那么使用一些不良的编码实践是没有意义的。
  • 好的,那么。干杯。

标签: php class oop object recursion


【解决方案1】:

是的。

这在多个层面都是错误的。

  • 您不应在类中的任何地方使用全局状态(与全局变量和单例/注册表有关)。
  • 你不应该在类的方法中回显,尤其是在构造函数中
  • 你不应该调用exit,除非是在“可怜的调试”的上下文中。
  • 您不应该在构造函数中创建不同类的新实例,因为它变得非常难以测试和调试
  • 您不应该滥用 extends 关键字,因为它用于创建基类的专用子类型

【讨论】:

    【解决方案2】:

    如果您期望变量$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 类的新实例覆盖。

    这没有什么是未定义的行为。 毫无意义,因为它一无所获。

    【讨论】:

    • 好吧,该死的,看来你是对的。谢谢。我会在 15 小时内给你赏金,如果时间限制允许我这样做。
    • @user6003859 不客气。很高兴能帮忙解释一下。
    猜你喜欢
    • 1970-01-01
    • 2019-11-07
    • 2013-09-28
    • 2019-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    相关资源
    最近更新 更多