Skip to content

Instantly share code, notes, and snippets.

@bxt
Created March 4, 2011 14:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bxt/854668 to your computer and use it in GitHub Desktop.
Save bxt/854668 to your computer and use it in GitHub Desktop.
Difference between private and public visibility PHP keywords (illustrative example)
<?php
class A {
private $foo="a";
protected $bar="a";
function getAstuff() {
return $this->foo.'/'.$this->bar;
}
}
class B extends A {
private $foo="b";
protected $bar="b";
function getBstuff() {
return $this->foo.'/'.$this->bar;
}
}
$b=new B();
echo 'getBstuff: '.$b->getBstuff()."\ngetAstuff: ".$b->getAstuff()."\n";
/*
Output:
getBstuff: b/b
getAstuff: a/b
As you see, methods defined in class A use the private vars of class A
even when used on an instance of child class B.
Protected attributes however are overridden just like private ones.
Notice that I do use overridden properties here.
You could not access $foo from B if it was not overwritten there.
*/
<?php
class A {
private function foo() {
return "a";
}
protected function bar() {
return "a";
}
function getAstuff() {
return $this->foo().'/'.$this->bar();
}
}
class B extends A {
private function foo() {
return "b";
}
protected function bar() {
return "b";
}
function getBstuff() {
return $this->foo().'/'.$this->bar();
}
}
$b=new B();
echo 'getBstuff: '.$b->getBstuff()."\ngetAstuff: ".$b->getAstuff()."\n";
/*
Output:
getBstuff: b/b
getAstuff: a/b
It's just the same thing with methods.
If I would not override foo() here it would throw an error:
"Fatal error: Call to private method A::foo() from context 'B' in /home/burny/privtest.php on line 23"
*/
<?php
abstract class A {
private static $foo="a";
protected static $bar="a";
function getAstuff() {
return self::$foo.'/'.self::$bar;
}
function getAstuffLateStatic() {
if(get_called_class()=="A") {
return static::$foo.'/'.static::$bar;
} else {
return /*static::$foo*/'X'.'/'.static::$bar;
}
}
}
class B extends A {
private static $foo="b";
protected static $bar="b";
function getBstuff() {
return self::$foo.'/'.self::$bar;
}
function getBstuffParent() {
return /*parent::$foo*/'X'.'/'.parent::$bar;
}
}
$b=new B();
echo 'B::getBstuff: '.B::getBstuff().
"\nB::getAstuff: ".B::getAstuff().
"\nB::getBstuffParent: ".B::getBstuffParent().
"\nB::getAstuffLateStatic: ".B::getAstuffLateStatic().
"\nA::getAstuffLateStatic: ".A::getAstuffLateStatic().
"\n";
/*
Output:
B::getBstuff: b/b
B::getAstuff: a/a
B::getBstuffParent: X/a
B::getAstuffLateStatic: X/b
A::getAstuffLateStatic: a/a
Things work similar in static contexts.
The difference is we can freely choose
between attributes of parent and child class
using parent, static and self.
When using self, we do always stay in the defining
class and we can access our own private attributes.
When using parent and static, we can only access
protected attributes, accessing the child's class
private properties throws this error:
PHP Fatal error: Cannot access private property B::$foo in /home/amoebe/Documents/854668/private_public_test_static.php on line 13
And accessing the parent's private stuff this one:
PHP Fatal error: Cannot access private property A::$foo in /home/amoebe/Documents/854668/private_public_test_static.php on line 25
Hence private locks access in both directions.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment