Metode statis dapat mengakses objek, bug, atau fitur pemanggil?

Saya sedang mengerjakan aplikasi saya dan menemukan perilaku aneh dari metode yang dipanggil secara statis tetapi tidak didefinisikan sebagai statis yang memperluas kelas yang sama. Pada akhirnya metode ini dapat mengakses dan mengubah variabel dan metode yang dilindungi pemanggil. Ini contoh kode saya:

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

Perilaku ini tidak didokumentasikan, jadi saya bertanya-tanya apakah ini bug atau fitur dan dapatkah ini menyebabkan masalah keamanan?

UPDATE. Saya mengetahui bahwa $this tidak diperbolehkan di dalam metode statis dan perilaku ini muncul di php versi 5.2.11


person Nazariy    schedule 12.09.2010    source sumber


Jawaban (1)


Perhatikan contoh ini di 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();
?>

Outputnya adalah:

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

Apa yang terjadi adalah penunjuk $this C::test() diasumsikan sebagai $this dari instance new B(). Jadi itu bertindak seperti fungsi anggota B, tetapi dengan akses C.

Itu hanya dapat mengakses variabel yang dilindungi dan publik dari A dan variabel publik dari B.

Perhatikan bahwa sebelum panggilan ke C::test(), $this->a memicu pemberitahuan. Setelah panggilan, hal itu tidak lagi dilakukan, karena variabel dibuat di dalam panggilan. Namun variabel pribadi A tidak dapat diakses.

Jadi ya, sebenarnya ini dianggap tidak valid di PHP 5.3. Dan bahkan jika versi sebelumnya membiarkan Anda melakukan ini tanpa peringatan (saya tidak memeriksa atau menelitinya), Anda tidak boleh mengandalkan perilaku tersebut karena ini jelas merupakan penyalahgunaan OOP.

person Matthew    schedule 16.09.2010