【问题标题】:Static method can access caller object, bug or feature?静态方法可以访问调用者对象、错误或功能?
【发布时间】:2011-04-11 09:01:48
【问题描述】:

我正在处理我的应用程序,发现静态调用但未定义为扩展同一类的静态方法的奇怪行为。最终,此方法可以访问和更改调用者受保护的变量和方法。 这是我的代码示例:

<?php

class object
{
    private $version;

    protected $alteredBy = 'nobody';

    public function __construct()
    {
        $this->version    = PHP_VERSION;

        $this->objectName = get_class($this);

        echo sprintf("<pre><strong>New %s Created</strong>", $this->objectName);

    }

    public function __destruct()
    {
        echo sprintf("</pre><strong>Source Code</strong><div>%s</div>", highlight_file(__FILE__, true));
    }
}

class superApplication extends object
{
    public function __toString()
    {
        echo "\nCalling third party object statically like thirdParty::method()\n";

        echo thirdParty::method();

        echo "\nCalling third party object statically via call_user_func()\n";

        echo call_user_func(array('thirdParty','method'));

        echo sprintf("New Object params\n%s", print_r($this, true));

        return sprintf("%s: done\n", $this->objectName);
    }
}

class thirdParty extends object
{    
    public function method()
    {
        if(is_object($this))
        {
            $this->alteredBy = __CLASS__;

            return sprintf(
                "<span style=\"color:red\">Object '%s' was altered successfully by %s class</span>\n", 
                get_class($this),
                __CLASS__
            );
        }
        else return "Cannot access caller object\n\n";        
    }
}

print new superApplication;
?>

这种行为没有记录在案,所以我想知道它是错误还是功能,是否会导致安全问题?

更新。 我知道 $this 在静态方法中是不允许的,这种行为出现在 php 版本 5.2.11

【问题讨论】:

    标签: php oop object methods static


    【解决方案1】:

    考虑 PHP 5.3 中的这个例子:

    <?php
            error_reporting(E_ALL | E_STRICT);
    
            class A
            {
                    private $a = 'A';
                    protected $b= 'B';
                    public $c = 'C';
            }
    
            class B extends A
            {
                    public function __construct()
                    {
                            var_dump($this->a, $this->b, $this->c);
                            C::test();
                            var_dump($this->a, $this->b, $this->c);
                    }
            }
    
            class C extends A
            {
                    public function test()
                    {
                            $this->a = null;
                            $this->b = null;
                            $this->c = null;
                    }
            }
    
            new B();
    ?>
    

    输出是:

    PHP Notice:  Undefined property: B::$a in ... on line 15
    NULL
    string(1) "B"
    string(1) "C"
    PHP Strict Standards:  Non-static method C::test() should not be called statically, assuming $this from incompatible context in ... on line 16
    NULL
    NULL
    NULL
    

    发生的情况是C::test()$this 指针被假定为来自new B() 实例的$this。所以它就像 B 的成员函数,但具有 C 的访问权限。

    它只能访问来自A 的受保护和公共变量以及来自B 的公共变量。

    请注意,在调用C::test() 之前,$this-&gt;a 触发了通知。调用之后,它不再这样做,因为变量是在调用中创建的。但是A 的私有变量在任何时候都无法访问。

    所以是的,严格来说,这在 PHP 5.3 中被认为是无效的。即使早期版本允许您在没有警告的情况下执行此操作(我没有检查或研究),您也不应该依赖这种行为,因为这显然是对 OOP 的滥用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-29
      • 2018-04-07
      相关资源
      最近更新 更多