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.
Class Friendship allows a class to be better encapsulated by granting per-class access to protected members.
Friend functions allow binary operators to be defined which combine private data in a pair of objects. This is particularly powerful when using the operator overloading features of C++. We will return to it when we look at overloading.
A friend function is used to access all the non-public members of a class. You can use a friend function to bridge two classes by operating objects of two different classes. It increases the versatility of overloading operators. It enhances encapsulation.
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
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With