PHP equivalent of friend or internal

前端 未结 4 1310
野的像风
野的像风 2020-12-01 07:21

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 st

相关标签:
4条回答
  • 2020-12-01 08:08

    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);
    
    0 讨论(0)
  • 2020-12-01 08:09

    maybe this ? only a hack not a real friends keyword from c++,In this case only for constructor...

    <?php
    
    class FooWithFriend {
    
        private function guardOnlyFriend(): void 
        {
            if (( is_a($this, BarFriendOfFoo::class) ) === false ) {
             throw new Exception('Only class BarFriendOfFoo he can create me');
            }
        }
    
        protected function __construct() 
        {
            $this->guardOnlyFriend();
            echo 'Hello friend - ';
        }
    }
    
    
    final class BarFriendOfFoo extends FooWithFriend {
        public function __construct()
        {
            parent::__construct();
        }
    }
    
    final class Bar2FriendOfFoo extends FooWithFriend {
        public function __construct()
        {
            parent::__construct();
        }
    }
    
    $bar = new BarFriendOfFoo();
    $bar = new Bar2FriendOfFoo();
    $dummy = new FooWithFriend();
    
    0 讨论(0)
  • 2020-12-01 08:13

    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)

    0 讨论(0)
  • 2020-12-01 08:21

    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

    0 讨论(0)
提交回复
热议问题