PHP equivalent of friend or internal

ⅰ亾dé卋堺 提交于 2019-12-17 09:29:11

问题


Is there some equivalent of "friend" or "internal" in php? If not, is there any pattern to follow to achieve this behavior?

Edit: Sorry, but standard Php isn't what I'm looking for. I'm looking for something along the lines of what ringmaster did.

I have classes which are doing C-style system calls on the back end and the juggling has started to become cumbersome. I have functions in object A which take in object B as a parameter and have to call a method in object B passing in itself as an argument. The end user could call the method in B and the system would fall apart.


回答1:


PHP doesn't support any friend-like declarations. It's possible to simulate this using the PHP5 __get and __set methods and inspecting a backtrace for only the allowed friend classes, although the code to do it is kind of clumsy.

There's some sample code and discussion on the topic on PHP's site:

class HasFriends
{
    private $__friends = array('MyFriend', 'OtherFriend');

    public function __get($key)
    {
        $trace = debug_backtrace();
        if(isset($trace[1]['class']) && in_array($trace[1]['class'], $this->__friends)) {
            return $this->$key;
        }

        // normal __get() code here

        trigger_error('Cannot access private property ' . __CLASS__ . '::$' . $key, E_USER_ERROR);
    }

    public function __set($key, $value)
    {
        $trace = debug_backtrace();
        if(isset($trace[1]['class']) && in_array($trace[1]['class'], $this->__friends)) {
            return $this->$key = $value;
        }

        // normal __set() code here

        trigger_error('Cannot access private property ' . __CLASS__ . '::$' . $key, E_USER_ERROR);
    }
}

(Code proved by tsteiner at nerdclub dot net on bugs.php.net)




回答2:


It is also possible to elevate privileges, aka leaking data selectively, using a handshake and closures in php >=5.3.3.

Basically, the interaction goes: class A has a public method which accepts a class B object, and calls B->grantAccess (or whatever your interface defines), passing it a closure. The closure use($that,$anythingelseyouneed) where $that=$this, and anything else you need to determine what properties are allowed to be accessed. The closure has one argument - the property to return; if it is a property on $that and everything is cool, the closure returns the property. Otherwise, it returns '', or throws an exception, or maybe a default value.

Class B->grantAccess accepts a callable and stores it, using it in other methods to pluck out private properties the closure allows to be leaked. Make class B's default constructor private. Construct a B using a static factory method that takes a Class A argument, to ensure the handshake happens.

Gist here: https://gist.github.com/mcamiano/00592fb400e5043d8acd




回答3:


I'm pretty sure what you're looking for is "protected" or "private", depending on your use case.

If you're defining an function in a class, and you only want it available to itself, you'll define it this way:

private function foo($arg1, $arg2) { /*function stuff goes here */ }

If you're defining a function in a class that you want to be available to classes which inherit from this class, but not available publicly, definite it this way:

protected function foo($arg1, $arg2)

I'm pretty sure that by default in PHP5, functions are public, meaning you don't have to use the following syntax, but it's optional:

public function foo($arg1, $arg2) { /*function stuff goes here */ }

You'll still have to instantiate the object before using a public function. So I'll just be thorough and let you know that in order to use a function in a class without instantiating an object, be sure to use the following syntax:

static function foo($arg1, $arg2) { /*function stuff goes here */ }

That will allow you to use the function by only referencing the class, as follows:

MyClass::foo($a1, $a2);

Otherwise, you'll need to do the following:

$myObject = new MyClass();
$myObject->foo($a1, $a2);


来源:https://stackoverflow.com/questions/317835/php-equivalent-of-friend-or-internal

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!