note 91850 added to language.oop5.visibility
| From: | adotschaffhirtatsedna-softdotde at osu1 dot php dot net | Date: | Mon, 29 Jun 2009 07:27:58 +0000 |
| Subject: | note 91850 added to language.oop5.visibility | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-157658@lists.php.net to get a copy of this message | ||
If you miss the "package" keyword in PHP in order to allow access between certain classes
without their members being public, you can utilize the fact, that in PHP the protected keyword
allows access to both subclasses and superclasses.
So you can use this simple pattern:
<?php
abstract class Dispatcher {
protected function &accessProperty (self $pObj, $pName) {
return $pObj->$pName;
}
protected function invokeMethod ($pObj, $pName, $pArgs) {
return call_user_func_array(array($pObj, $pName), $pArgs);
}
}
?>
The classes that should be privileged to each other simply extend this dispatcher:
<?php
class Person extends Dispatcher {
private $name;
protected $phoneNumbers;
public function __construct ($pName) {
$this->name = $pName;
$this->phoneNumbers = array();
}
public function addNumber (PhoneNumber $pNumber, $pLabel) {
$this->phoneNumbers[$pLabel] = $pNumber;
// this does not work, because "owner" is protected:
// $pNumber->owner = $this;
// instead, we get a reference from the dispatcher:
$p =& $this->accessProperty($pNumber, "owner");
// ... and change that:
$p = $this;
}
public function call ($pLabel) {
// this does not work since "call" is protected:
// $this->phoneNumbers[$pLabel]->call();
// instead, we dispatch the call request:
$this->invokeMethod($this->phoneNumbers[$pLabel], "call", array());
}
}
class PhoneNumber extends Dispatcher {
private $countryCode;
private $areaCode;
private $number;
protected $owner;
public function __construct ($pCountryCode, $pAreaCode, $pNumber) {
$this->countryCode = $pCountryCode;
$this->areaCode = $pAreaCode;
$this->number = $pNumber;
}
protected function call () {
echo("calling " . $this->countryCode . "-" . $this->areaCode .
"-" . $this->number . "\n");
}
}
$person = new Person("John Doe");
$number1 = new PhoneNumber(12, 345, 67890);
$number2 = new PhoneNumber(34, 5678, 90123);
$person->addNumber($number1, "home");
$person->addNumber($number2, "office");
$person->call("home");
?>
Without this pattern you would have to make $owner and call() public in PhoneNumber.
Best regards,
----
Server IP: 217.13.201.10
Probable Submitter: 77.179.100.83
----
Manual Page -- http://www.php.net/manual/en/language.oop5.visibility.php
Edit -- https://master.php.net/note/edit/91850
Del: integrated -- https://master.php.net/note/delete/91850/integrated
Del: useless -- https://master.php.net/note/delete/91850/useless
Del: bad code -- https://master.php.net/note/delete/91850/bad+code
Del: spam -- https://master.php.net/note/delete/91850/spam
Del: non-english -- https://master.php.net/note/delete/91850/non-english
Del: in docs -- https://master.php.net/note/delete/91850/in+docs
Del: other reasons-- https://master.php.net/note/delete/91850
Reject -- https://master.php.net/note/reject/91850
Search -- https://master.php.net/manage/user-notes.php