Область видимости

Область видимости свойства или метода может быть определена путем использования следующих ключевых слов в объявлении: public, protected или private. Доступ к свойствам и методам классам, объявленным как public (общедоступный), может происходить из любого места. Модификатор protected (защищенный) позволяет иметь доступ наследуемым и родительским классам (а, также классу, в котором определен сам член класса). Модификатор private (закрытый) ограничивает область видимости так, что только класс, где объявлен сам элемент, имеет к нему доступ.

Область видимости свойств

Свойства класса должны быть определены через модификаторы public, private, или protected.

Пример #1 Объявление свойства класса

<?php
/**
 * Определение MyClass
 */
class MyClass
{
    public 
$public 'Общий';
    protected 
$protected 'Защищенный';
    private 
$private 'Закрытый';

    function 
printHello()
    {
        echo 
$this->public;
        echo 
$this->protected;
        echo 
$this->private;
    }
}

$obj = new MyClass();
echo 
$obj->public// Работает
echo $obj->protected// Неисправимая ошибка
echo $obj->private// Неисправимая ошибка
$obj->printHello(); // Выводит Общий, Защищенный и Закрытый


/**
 * Определение MyClass2
 */
class MyClass2 extends MyClass
{
    
// Мы можем переопределить public и protected методы, но не private
    
protected $protected 'Защищенный2';

    function 
printHello()
    {
        echo 
$this->public;
        echo 
$this->protected;
        echo 
$this->private;
    }
}

$obj2 = new MyClass2();
echo 
$obj2->public// Работает
echo $obj2->private// Неопределен
echo $obj2->protected// Неисправимая ошибка
$obj2->printHello(); // Выводит Общий, Защищенный2 и Закрытый

?>

Замечание: Метод объявления переменной через ключевое слово var, принятый в PHP 4, до сих пор поддерживается в целях совместимости (как синоним ключевого слова public). В версиях PHP 5 ниже 5.1.3 такое использование выводит предупреждение E_STRICT.

Область видимости метода

Методы класса должны быть определены через модификаторы public, private, или protected. Методы, где определение модификатора отсутствует, определяются как public.

Пример #2 Объявление метода

<?php
/**
 * Определение MyClass
 */
class MyClass
{
    
// Объявление общедоступного конструктора
    
public function __construct() { }

    
// Объявление общедоступного метода
    
public function MyPublic() { }

    
// Объявление защищенного метода
    
protected function MyProtected() { }

    
// Объявление закрытого метода
    
private function MyPrivate() { }

    
// Это общедоступный метод
    
function Foo()
    {
        
$this->MyPublic();
        
$this->MyProtected();
        
$this->MyPrivate();
    }
}

$myclass = new MyClass;
$myclass->MyPublic(); // Работает
$myclass->MyProtected(); // Неисправимая ошибка
$myclass->MyPrivate(); // Неисправимая ошибка
$myclass->Foo(); // Работает общий, защищенный и закрытый


/**
 * Определение MyClass2
 */
class MyClass2 extends MyClass
{
    
// Это общедоступный метод
    
function Foo2()
    {
        
$this->MyPublic();
        
$this->MyProtected();
        
$this->MyPrivate(); // Неисправимая ошибка
    
}
}

$myclass2 = new MyClass2;
$myclass2->MyPublic(); // Работает
$myclass2->Foo2(); // Работает общий и защищенный, закрытый не работает

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
?>

Коментарии

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($b3);
$b->setForeignBar($a4);
$a->debugBar($b);        // 3
$b->debugBar($a);        // 4
?>
2006-01-05 07:11:33
http://php5.kiev.ua/manual/ru/language.oop5.visibility.html
Автор:
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 
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
?>
2007-05-29 15:09:08
http://php5.kiev.ua/manual/ru/language.oop5.visibility.html
if not overwritten, self::$foo in a subclass actually refers to parent's self::$foo 
<?php
class one
{
    protected static 
$foo "bar";
    public function 
change_foo($value)
    {
       
self::$foo $value;
    }
}

class 
two extends one
{
    public function 
tell_me()
    {
        echo 
self::$foo;
    }
}
$first = new one;
$second = new two;

$second->tell_me(); // bar
$first->change_foo("restaurant");
$second->tell_me(); // restaurant
?>
2012-06-21 05:31:23
http://php5.kiev.ua/manual/ru/language.oop5.visibility.html
Just a quick note that it's possible to declare visibility for multiple properties at the same time, by separating them by commas.

eg:

<?php
class a
{
    protected 
$a$b;

    public 
$c$d;

    private 
$e$f;
}
?>
2015-06-30 14:09:18
http://php5.kiev.ua/manual/ru/language.oop5.visibility.html
> Members declared protected can be accessed only within 
> the class itself and by inherited classes. Members declared 
> as private may only be accessed by the class that defines 
> the member.

This is not strictly true. Code outside the object can get and set private and protected members:

<?php
class Sealed { private $value 'foo'; }

$sealed = new Sealed;
var_dump($sealed); // private $value => string(3) "foo"

call_user_func(\Closure::bind(
    function () use (
$sealed) { $sealed->value 'BAZ'; },
   
null,
   
$sealed
));

var_dump($sealed); // private $value => string(3) "BAZ"

?>

The magic lay in \Closure::bind, which allows an anonymous function to bind to a particular class scope. The documentation on \Closure::bind says:

> If an object is given, the type of the object will be used
> instead. This determines the visibility of protected and
> private methods of the bound object.

So, effectively, we're adding a run-time setter to $sealed, then calling that setter. This can be elaborated to generic functions that can force set and force get object members:

<?php
function force_set($object$property$value) {
   
call_user_func(\Closure::bind(
        function () use (
$object$property$value) {
           
$object->{$property} = $value;
        },
       
null,
       
$object
   
));
}

function 
force_get($object$property) {
    return 
call_user_func(\Closure::bind(
        function () use (
$object$property) {
            return 
$object->{$property};
        },
       
null,
       
$object
   
));
}

force_set($sealed'value''quux');
var_dump(force_get($sealed'value')); // 'quux'

?>

You should probably not rely on this ability for production quality code, but having this ability for debugging and testing is handy.
2016-11-11 17:27:01
http://php5.kiev.ua/manual/ru/language.oop5.visibility.html
I see we can redeclare private properties into child class 
<?php   
 
class A{
        private 
int $private_prop 4;
        protected 
int $protected_prop 8;
    }

    class 
extends A{
        private 
int $private_prop 7// we can redeclare private property!!!
       
public function printAll() {
            echo 
$this->private_prop;
            echo 
$this->protected_prop;
    }
    }

   
$b = new B;
   
$b->printAll(); // show 78
}
?>
2021-08-24 01:05:14
http://php5.kiev.ua/manual/ru/language.oop5.visibility.html
Dynamic properties are "public".
<?php
class MyClass {
    public function 
setProperty($value) {
       
$this->dynamicProperty $value;
    }
}
$obj = new MyClass();
$obj->setProperty('Hello World');
echo 
$obj->dynamicProperty// Outputs "Hello World"
?>

This usage is the same as well:
<?php
class MyClass {
}
$obj = new MyClass();
$obj->dynamicProperty 'Hello World';
echo 
$obj->dynamicProperty// Outputs "Hello World"
?>
2023-04-17 11:57:13
http://php5.kiev.ua/manual/ru/language.oop5.visibility.html

    Поддержать сайт на родительском проекте КГБ