Please note that if a class has a protected variable, a subclass cannot have the same variable redefined private (must be protected or weaker). It seemed to be logical for me as a subsubclass would not know if it could see it or not but even if you declare a subclass to be final the restriction remains.
アクセス権
プロパティまたはメソッドのアクセス権 (visibility) は、 キーワード: public, protected または private を指定することにより、 定義できます。 public として定義されたアイテムには、どこからでもアクセス可能です。 protected は、派生クラスや親クラス (とそれを定義するクラス自体) にアクセスを制限します。private は、 それを定義するクラスのみにアクセス権を制限します。
メンバのアクセス権
クラスのメンバは、public, private, または protected として定義されなくてはなりません。
例1 メンバの宣言
<?php
/**
* MyClass の定義
*/
class MyClass
{
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // 動作します
echo $obj->protected; // Fatal エラー
echo $obj->private; // Fatal エラー
$obj->printHello(); // Public、Protected そして Private を表示します
/**
* MyClass2 の定義
*/
class MyClass2 extends MyClass
{
// public および protected メソッドは再定義できますが、
// private はできません。
protected $protected = 'Protected2';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj2 = new MyClass2();
echo $obj2->public; // 動作します
echo $obj2->private; // 未定義です
echo $obj2->protected; // Fatal エラー
$obj2->printHello(); // Public、Protected2、Undefined を表示します
?>
注意: キーワード var で変数を宣言する PHP 4 の方法は、互換性を保つために今でもサポートされています (これは public と同じ扱いになります)。PHP 5.1.3 より前では、 これを使用すると E_STRICT 警告が発生します。
メソッドのアクセス権
クラスメソッドは、public, private, または protected として定義される必要があります。どの宣言も有さないメソッドは、 public として定義されます。
例2 メソッドの宣言
<?php
/**
* MyClass の定義
*/
class MyClass
{
// public コンストラクタの宣言
public function __construct() { }
// public メソッドの宣言
public function MyPublic() { }
// protected メソッドの宣言
protected function MyProtected() { }
// private メソッドの宣言
private function MyPrivate() { }
// これは public となります
function Foo()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
$myclass = new MyClass;
$myclass->MyPublic(); // 動作します
$myclass->MyProtected(); // Fatal エラー
$myclass->MyPrivate(); // Fatal エラー
$myclass->Foo(); // Public、Protected および Private が動作します
/**
* MyClass2 の定義
*/
class MyClass2 extends MyClass
{
// これは public となります
function Foo2()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate(); // Fatal エラー
}
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // 動作します
$myclass2->Foo2(); // Public および Protected は動作しますが、Private は動作しません
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
?>
アクセス権
omnibus at omnibus dot edu dot pl
13-Dec-2007 06:34
13-Dec-2007 06:34
phpdoc at povaddict dot com dot ar
11-Oct-2007 12:52
11-Oct-2007 12:52
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'.";
?>
Joshua Watt
29-May-2007 12:09
29-May-2007 12:09
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
?>
ference at super_delete_brose dot co dot uk
22-May-2007 10:10
22-May-2007 10:10
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();
?>
nanocaiordo at gmail dot com
08-Apr-2007 06:49
08-Apr-2007 06:49
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
}
?>
Alex
14-Mar-2007 10:33
14-Mar-2007 10:33
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.
atitthaker at gmail dot com
01-Mar-2007 01:34
01-Mar-2007 01:34
<?
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.
stephane at harobed dot org
23-Aug-2006 02:22
23-Aug-2006 02:22
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.
kakugo at kakugo dot com
13-Jul-2006 03:19
13-Jul-2006 03:19
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.
LoN_Kamikaze at gmx dot de
28-Mar-2006 01:26
28-Mar-2006 01:26
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.
c3 at epetersen dot org
06-Feb-2006 05:50
06-Feb-2006 05:50
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).
r dot wilczek at web-appz dot de
05-Jan-2006 05:11
05-Jan-2006 05:11
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
?>
gugglegum at gmail dot com
02-Sep-2005 03:14
02-Sep-2005 03:14
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!"
?>
Miguel <miguel at lugopolis dot net>
21-Jul-2005 08:10
21-Jul-2005 08:10
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.
