|
VisibilityThe visibility of a property or method can be defined by prefixing the declaration with the keywords: public, protected or private. Public declared items can be accessed everywhere. Protected limits access to inherited and parent classes (and to the class that defines the item). Private limits visibility only to the class that defines the item. Class members must be defined with public, private, or protected. Example 10.10. Member declaration<?php
Note:
The PHP 4 method of declaring a variable with the
var keyword is still supported for compatibility
reasons (as a synonym for the public keyword). In PHP 5 before 5.1.3, its
usage would generate an Class methods must be defined with public, private, or protected. Methods without any declaration are defined as public. Example 10.11. Method Declaration<?php Code Examples / Notes » language.oop5.visibilitydavid rech
You may define grouped variables separated by commas if they have the same visibility. This works for both initialized and uninitialized variables. <? class Window { public $x = 0, $y = 100, $width = 1024, $height = 768; } ?> Handy if no comments are required or you're inside a DocBlock. gugglegum
When you call parent method from child class, inside parent method $this contains object of child class, but private members depends on from which context you access private property: <?php class A { private $prop = "I am property of A!"; public function s() { echo "\$this is object of class ".get_class($this)." but \$this->prop is '".$this->prop."'\n"; } } class B extends A { private $prop = "I am property of B!"; public function s() { echo "\$this is object of class ".get_class($this)." but \$this->prop is '".$this->prop."'\n"; } public function z() { parent::s(); $this->s(); } } $b = new B(); $b->z(); ?> This will produce: $this is object of class B but $this->prop is 'I am property of A!' $this is object of class B but $this->prop is 'I am property of B!' But when you use members with protected or public visibility - it not depends on context. If you replace "private" to "protected" in example above, you will get "I am property of B!" twice. See ya! alex
Uh... to atitthaker at gmail dot com -- It is *meant* to be available under C as well, since A is a superclass of C, and any proctected methods in a superclass is always available to a subclass, no matter how many "generations" you have to traverse, it is available to C.
thc
To jfk... Interessting and probably a bug? Well, the workaround is not very hard: Just don't return the member directly: <? public function GetNum(){ $ret = $this->num; return $ret; } ?> kakugo
This refers to previous notes on protected members being manipulated externally: It is obvious that if you were to allow methods the option of replacing protected variables with external ones it will be possible, but there is no reason not to simply use a protected method to define these, or not to write the code to allow it. Just because it is possible doesn't mean it's a problem, it simply does not allow you to be lax on the security of the class. alberi
There is such nonstricted "feature" with self:: on dinamic & static calling of methods not declared as static: <? class foo { static $counter; public function bar($i=0) { if ($i) self::$counter = $i; echo ' bar: $this var ', isset($this)?'exists':'missing', "\n"; self::mar(); if (--self::$counter) self::bar(); } public function mar() { echo ' mar: $this var ', isset($this)?'exists':'missing', "\n"; } } $foo = new foo(); echo "\nDINAMIC CALLING:\n"; $foo->bar(2); echo "\nSTATIC CALLING:\n"; foo::bar(2); # OUTPUT: # # DINAMIC CALLING: # bar: $this var exists # mar: $this var exists # bar: $this var exists # mar: $this var exists # # STATIC CALLING: # bar: $this var missing # mar: $this var missing # bar: $this var missing # mar: $this var missing # # # executed under PHP 5.1.1 (cli) (built: Nov 27 2005 21:39:02) ?> In other words, in dinamic called function the "self::" selector will be interpreted as "$this->". ference
Sometimes you may wish to have all members of a class visible to other classes, but not editable - effectively read-only. In this case defining them as public or protected is no good, but defining them as private is too strict and by convention requires you to write accessor functions. Here is the lazy way, using one get function for accessing any of the variables: <?php class Foo { private $a; private $b; private $c; private $d; private $e; private $f; public function __construct() { $this->a = 'Value of $a'; $this->b = 'Value of $b'; $this->c = 'Value of $c'; $this->d = 'Value of $d'; $this->e = 'Value of $e'; $this->f = 'Value of $f'; } /* Accessor for all class variables. */ public function get($what) { $result = FALSE; $vars = array_keys(get_class_vars('Foo')); foreach ($vars as $var) { if ($what == $var) { eval('$result = $this->'.$var.';'); return $result; } } return $result; } } class Bar { private $a; public function __construct() { $foo = new Foo(); var_dump($foo->get('a')); // results in: string(11) "Value of $a" } } $bar = new Bar(); ?> phpdoc
Re: ference at super_delete_brose dot co dot uk "If eval() is the answer, youâre almost certainly asking the wrong question." <?php eval('$result = $this->'.$var.';'); //wrong $result = $this->$var; //right way $var = "foo"; $this->var = "this will assign to member called 'var'."; $this->$var = "this will assign to member called 'foo'."; ?> gugglegum
Private visibility actually force members to be not inherited instead of limit its visibility. There is a small nuance that allows you to redeclare private member in child classes. <?php class A { private $prop = 'I am property of A!'; } class B extends A { public $prop = 'I am property of B!'; } $b = new B(); echo $b->prop; // "I am property of B!" ?> chris
One note that I have not found in the documentation but have found to be valid is a alternative syntax for visibility assignment. Take into consideration a previous example of: <?php class Foo { const sudo = 'sudo'; const finger = 'finger'; const strings = 'strings; private $a; private $b; private $c; private $d; private $e; private $f; protected $g; protected $h; protected $i; protected $j; public $k; public $l; public $m; public function __construct() {} } ?> Can also be written, slightly more elegantly as: <?php class Foo { const sudo = 'sudo', finger = 'finger', const strings = 'strings; private $a, $b, $c, $d, $e, $f; protected $g, $h, $i, $j; public $k, $l, $m; public function __construct() {} } ?> Just make sure to end the assignment with your semicolon, and separate assignment with commas. c3
Note that you cannot change visibility in a child defined in the parent: class A { public function f() {} } class B extends A { private function f() {} } Produces Fatal error: Access level to B::f() must be public (as in class A) in ... jfk, visibility != security. Visibility prevents programmers from doing dumb things like: class A { private function __construct() {} final public static &factory() { return new A(); } } $x = new A(); The use of "protected" as an identifier is unfortunate tradition as it really means "only me and my decedents" (and in the odd case of PHP my ancestors too). nanocaiordo
If you always thought how can you use a private method in php4 classes then try the following within your class. <?php function private_func($func) { $this->file = __FILE__; if (PHPVERS >= 43) { $tmp = debug_backtrace(); for ($i=0; $i<count($tmp); ++$i) { if (isset($tmp[$i]['function'][$func])) { if ($this->file != $tmp[$i]['file']) { trigger_error('Call to a private method '.__CLASS__.'::'.$func.' in '.$tmp[$i]['file'], E_USER_ERROR); } } } } } ?> Then inside the private function add: <?php function foo() { $this->private_func(__FUNCTION__); # your staff goes here } ?> joshua watt
I couldn't find this documented anywhere, but you can access protected and private member varaibles in different instance of the same class, just as you would expect i.e. <?php class A { protected $prot; private $priv; public function __construct($a, $b) { $this->prot = $a; $this->priv = $b; } public function print_other(A $other) { echo $other->prot; echo $other->priv; } } class B extends A { } $a = new A("a_protected", "a_private"); $other_a = new A("other_a_protected", "other_a_private"); $b = new B("b_protected", "ba_private"); $other_a->print_other($a); //echoes a_protected and a_private $other_a->print_other($b); //echoes b_protected and ba_private $b->print_other($a); //echoes a_protected and a_private ?> r dot wilczek
Beware: Visibility works on a per-class-base and does not prevent instances of the same class accessing each others properties! <?php class Foo { private $bar; public function debugBar(Foo $object) { // this does NOT violate visibility although $bar is private echo $object->bar, "\n"; } public function setBar($value) { // Neccessary method, for $bar is invisible outside the class $this->bar = $value; } public function setForeignBar(Foo $object, $value) { // this does NOT violate visibility! $object->bar = $value; } } $a = new Foo(); $b = new Foo(); $a->setBar(1); $b->setBar(2); $a->debugBar($b); // 2 $b->debugBar($a); // 1 $a->setForeignBar($b, 3); $b->setForeignBar($a, 4); $a->debugBar($b); // 3 $b->debugBar($a); // 4 ?> jfk
BEWARE!! The visibility of a class member can easily be compromised by attaining a reference to the protected member. In C++ for example this can not be done unless specifically included in the declaration/definition. However in PHP it is simple!!!! Observe.... class MyClass{ protected $num; public function MyClass(){ $this->num = 0; } public function Increment(){ $this->num++; } public function GetNum(){ return $this->num; } }; $c = new MyClass(); //create instance of class $x = &$c->GetNum(); //create variable referencing protected member to keep track of value while avoiding repeat calls to GetNum(). $x++; echo "CLASS VALUE: " . $c->GetNum() . " VAR VALUE: $x\n"; The output is: CLASS VALUE: 1 VAR VALUE: 1 A protected member should be exactly what "protected" means, protected. I hope I am overlooking something. If not I believe this feature should be corrected to improve transparency in syntax between the two "languages." Additionally, please note that my email address is: jkallen@206-225-86-169.dedicated.abac.net I had to create the jfk alias because the form for submitting notes does not accept emails as long as mine!!!! Ouch! lon_kamikaze
About the previous note: Of course you cannot declare public attributes/methods private, because it can break code relying on access to such an attribute/method. But of course your children can override private with protected/public. miguel
A note about private members, the doc says "Private limits visibility only to the class that defines the item" this says that the following code works as espected: <?php class A { private $_myPrivate="private"; public function showPrivate() { echo $this->_myPrivate."\n"; } } class B extends A { public function show() { $this->showPrivate(); } } $obj=new B(); $obj->show(); // shows "private\n"; ?> this works cause A::showPrivate() is defined in the same class as $_myPrivate and has access to it. stephane
A class A static public function can access to class A private function : <?php class A { private function foo() { print("bar"); } static public function bar($a) { $a->foo(); } } $a = new A(); A::bar($a); ?> It's working. atitthaker
<? class A { protected $b=20; private $a=10; //protected method and shall not be accessible under class C protected function access() { print("here"); } } class B extends A { public function test() { $this->access() ; } } class C extends B { function temp() { $this->access(); // access variable and prints "here" } } $abc= new C(); $abc->temp(); ?> Above code shall generate error as protected method of class A is accessible in class C which is directly not inheriting class A. |
Change LanguageIntroduction The Basics Autoloading Objects Constructors and Destructors Visibility Scope Resolution Operator (::) Static Keyword Class Constants Class Abstraction Object Interfaces Overloading Object Iteration Patterns Magic Methods Final Keyword Object cloning Comparing objects Reflection Type Hinting Late Static Bindings |