Call a protected method from outside a class in PH

2019-03-29 08:40发布

I have a very special case in which I need to call a protected method from outside a class. I am very conscious about what I do programmingwise, but I would not be entirely opposed to doing so in this one special case I have. In all other cases, I need to continue disallowing access to the internal method, and so I would like to keep the method protected.

What are some elegant ways to access a protected method outside of a class? So far, I've found this.

I suppose it may be possible create some kind of double-agent instance of the target class that would sneakily provide access to the internals...

6条回答
beautiful°
2楼-- · 2019-03-29 08:48

I'm just throwing this out there since I haven't programmed in PHP in two years. Could you just add a function to the class that calls the protected method like so?

$obj->publicFunc = create_function('$arg', 'return $this->protectedFunc($arg);');

Edit: I think Tom's correct in looking at the documentation for create_function. It looks like the scope of $this will be "wrong" when you try to call it with this example.


It looks like traditional anonymous functions are supported since PHP 5.3.0 as well (and my first solution probably won't work), so I'd probably write it like this instead:

$obj->publicFunc = function($arg) { 
     return $this->protectedFunc($arg); 
};

Since I think it looks a little cleaner (and your IDE of choice will highlight it better of course).


Ugh, I tried using Reflection to call the method but PHP won't allow you to do that either. It seems that you're going to have to use some sort of child class like the other posters have suggested. If you find a method that works, the developers will likely classify it as a bug in the future and break your code when you upgrade to the next version.

I recommend extending the class.

查看更多
小情绪 Triste *
3楼-- · 2019-03-29 08:50

This is a little kludgy, but might be an option.

Add a child class for the sake of accessing your protected function

public class Child extends Parent {
    public function protectedFunc() {
        return parent::protectedFunc();
    }
}

Then, instantiate an instance of Child instead of Parent where you need to call that function.

查看更多
你好瞎i
4楼-- · 2019-03-29 08:57

I would think that in this case, refactoring so you don't require this sort of thing is probably the most elegant way to go. In saying that one option is to use __call and within that parse debug_backtrace to see which class called the method. Then check a friends whitelst

class ProtectedClass {

    // Friend list
    private $friends = array('secret' => array('FriendClass')); 

    protected function secret($arg1, $arg2) {
        // ...
    }

    public function __call($method, $args) {

        $trace = debug_backtrace();
        $class = $trace[1]['class'];
        if(in_array($class, $this->friends[$method]))
            return $this->$method($args[0], $args[1]);

        throw new Exception();
    }
}

I think I need a shower.

查看更多
虎瘦雄心在
5楼-- · 2019-03-29 09:03

In PHP you can do this using Reflections. To invoke protected or private methods use the setAccessible() method http://php.net/reflectionmethod.setaccessible (just set it to TRUE)

查看更多
\"骚年 ilove
6楼-- · 2019-03-29 09:04

Suppose your method declaration goes like so:

protected function getTheFoo() {
    ...
}

protected function setTheFoo($val) {
    ...
}

Usage:

$obj->__get('the_foo');
$obj->__set('the_foo', 'myBar');

This bypasses the protected methods and goes directly straight to the instance variables.

查看更多
做个烂人
7楼-- · 2019-03-29 09:09

I'd think about what is the matter with the program design if I have to call a private function?

It used to be the case when

  • your class is responsible for several things (it is really two or thre calsses wrapped together) or
  • the rules of encapsulation are broken (utility functions, for example)

By finding any way to walk around this questions, you'll be nowhere nearer to the real solution.

查看更多
登录 后发表回答