Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does $new = new self($data); lets you access private functions and variables?

I have a strange behavior in my PHP 5.3. I have a class which does this in a function:

$new = new self($data);
$new->setServiceManager($this->service);
$new->cacheInstance();

BUT the function cacheInstance is a private function...

private function cacheInstance()
{
    foreach ($this->data as $name => $class) {...}
}

Can some one give an explanation why the hell can this be used like this? Shouldn't this method be private aka inaccessible from outside?

I can even access the private variables of the instance... like what the ... this has to be some intended behavior, can someone point me in a direction?

like image 931
Sangoku Avatar asked Dec 12 '25 02:12

Sangoku


2 Answers

If you can create a class instance with new self() it means you are in the class, and of course you can access private properties an functions. This snippet is taken from the PHP Docs (link)

/**
 * Define MyClass
 */
class MyClass
{
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';

    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}

$obj = new MyClass();
echo $obj->public; // Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
$obj->printHello(); // Shows Public, Protected and Private

IN YOUR CASE:

class Cache {
    private $service = null;

    private function cacheInstance()
    {
        foreach ($this->data as $name => $class) {}
    }

    public function setServiceManager( $service ) {

    }

    public function myTest( $data ) {
        $new = new self( $data );// you are in the class, so you can call new self()
        $new->setServiceManager($this->service);
        $new->cacheInstance();
    }
}
$cache = new Cache();
$cache->service; //Fatal error: Cannot access private property

$data = array();
$cache->myTest( $data );// working

$cache->cacheInstance();// not working
like image 78
swidmann Avatar answered Dec 14 '25 16:12

swidmann


private, protected and public accessibility works on class level, not on object level.

While it may seem counter intuitive first, this is not your usual PHP weirdness.

It's the same in other OOP languages, like Java

Note that accessibility is a static property that can be determined at compile time; it depends only on types and declaration modifiers.

and C#

The private keyword is a member access modifier. Private access is the least permissive access level. Private members are accessible only within the body of the class or the struct in which they are declared

(highlights added)

Explanation

The accessibility is a mechanism to hide implementation details from code in other classes, not for encapsulation of objects. Or as it's stated in the Java specs, accessibility can be determined at compile time, i.e. there cannot be a runtime violation because it's a different object.

It makes sense, if you look at the difference between private and protected. For private members, an object does not have access to its own members if they are declared in a parent class. Sounds weird? That's because the terminology is wrong. The class does not have access to privates of its parent class (i.e. it may not use them).

Now in your method, you use private variables within the same class. There is no need to hide this implementation detail from yourself, the author of this class, no matter what the objects are at runtime.

like image 45
Fabian Schmengler Avatar answered Dec 14 '25 16:12

Fabian Schmengler



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!