PHP.mk документација

Видливост

Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.

language.oop5.visibility.php PHP.net прокси Преводот се освежува
Оригинал на PHP.net
Патека language.oop5.visibility.php Локална патека за оваа страница.
Извор php.net/manual/en Оригиналниот HTML се реупотребува и локално се стилизира.
Режим Прокси + превод во позадина Кодовите, табелите и белешките остануваат читливи во истиот тек.
Видливост

Референца за `language.oop5.visibility.php` со подобрена типографија и навигација.

language.oop5.visibility.php

Видливост

The visibility of a property, a method or (as of PHP 7.1.0) a constant can be defined by prefixing the declaration with the keywords public, protected or privateВидливоста на својство, метод или (од PHP 7.1.0) константа може да се дефинира со додавање на клучните зборови

. Членовите на класата декларирани како јавни (public) може да се пристапат насекаде. Членовите декларирани како заштитени (protected) може да се пристапат само во самата класа и од класи што наследуваат и родителски класи. Членовите декларирани како приватни (private) може да се пристапат само од класата што го дефинира членот.

Видливост на класата

Својствата на класата може да се дефинираат како јавни (public), приватни (private) или заштитени (protected). Својствата декларирани без експлицитен клуч збор за видливост се дефинираат како јавни (public).

<?php
/**
* Define 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; // Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
$obj->printHello(); // Shows Public, Protected and Private


/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// We can redeclare the public and protected properties, but not private
public $public = 'Public2';
protected
$protected = 'Protected2';

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

$obj2 = new MyClass2();
echo
$obj2->public; // Works
echo $obj2->protected; // Fatal Error
echo $obj2->private; // Undefined
$obj2->printHello(); // Shows Public2, Protected2, Undefined

?>

Пример #1 Декларација на својство

Асиметрична видливост на својствоgetОд PHP 8.4, својствата на објектите исто така може да имаат видливост поставена асиметрично, со различен опсег за читање (set) и пишување ( set ). Поточно,

видливоста може да се специфицира одделно, под услов да не е попермисивна од стандардната видливост.

<?php
class Book
{
public function
__construct(
public private(
set) string $title,
public protected(
set) string $author,
protected private(
set) int $pubYear,
) {}
}

class
SpecialBook extends Book
{
public function
update(string $author, int $year): void
{
$this->author = $author; // OK
$this->pubYear = $year; // Fatal Error
}
}

$b = new Book('How to PHP', 'Peter H. Peterson', 2024);

echo
$b->title; // Works
echo $b->author; // Works
echo $b->pubYear; // Fatal Error

$b->title = 'How not to PHP'; // Fatal Error
$b->author = 'Pedro H. Peterson'; // Fatal Error
$b->pubYear = 2023; // Fatal Error
?>

Пример #2 Асиметрична видливост на својство set Од PHP 8.5,

видливоста исто така може да се примени на статични својства на класи.

<?php
class Manager
{
public private(
set) static int $calls = 0;

public function
doAThing(): string
{
self::$calls++;
// Do other stuff.
return "some string";
}
}

$m = new Manager();

$m->doAThing(); // Works
echo Manager::$calls; // Works
Manager::$calls = 5; // Fatal error
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

1
Fatal error: Uncaught Error: Cannot modify private(set) property Manager::$calls from global scope in /some/file.php

Пример #3 Асиметрична видливост на статично својство

  • Постојат неколку предупредувања во врска со асиметричната видливост: set visibility.
  • На set Само типизирани својства може да имаат посебна get видливост мора да биде иста како public protected(set) and protected protected(set) или порестриктивна. Тоа е, protected public(set) се дозволени, но
  • Ако еден имот е public, тогаш главната видливост може да се изостави. Тоа е, public private(set) and private(set) ќе го има истиот резултат.
  • Имот со private(set) видливост е автоматски final, и не може повторно да се декларира во дете класа.
  • Добивањето референца до имот следи set , не get. Тоа е затоа што референцата може да се користи за менување на вредноста на имотот.
  • Слично, обидот за запишување во имот од тип низа вклучува и get and set операција внатрешно, и затоа ќе следи set видливост, бидејќи тоа секогаш е порестриктивно.

Забелешка: Просторите не се дозволени во декларацијата за поставување видливост. private(set) е точно. private( set ) не е точно и ќе резултира со грешка при парсирање.

Кога една класа наследува друга, дете класата може повторно да дефинира кој било имот што не е final. Кога го прави тоа, може да ја прошири или главната видливост или set видливост, под услов новата видливост да е иста или поширока од родителската класа. Сепак, бидете свесни дека ако private имот е презапишан, тоа всушност не ја менува родителската сопственост, туку создава нова сопственост со различно внатрешно име.

Пример #4 Асиметрично наследување на имоти

<?php
class Book
{
protected
string $title;
public protected(
set) string $author;
protected private(
set) int $pubYear;
}

class
SpecialBook extends Book
{
public protected(
set) string $title; // OK, as reading is wider and writing the same.
public string $author; // OK, as reading is the same and writing is wider.
public protected(set) int $pubYear; // Fatal Error. private(set) properties are final.
}
?>

Видливост на методи

Методите на класата може да бидат дефинирани како јавни, приватни или заштитени. Методите декларирани без експлицитен клуч збор за видливост се дефинирани како јавни.

Пример #5 Декларација на метод

<?php
/**
* Define MyClass
*/
class MyClass
{
// Declare a public constructor
public function __construct() { }

// Declare a public method
public function MyPublic() { }

// Declare a protected method
protected function MyProtected() { }

// Declare a private method
private function MyPrivate() { }

// This is public
function Foo()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}

$myclass = new MyClass;
$myclass->MyPublic(); // Works
$myclass->MyProtected(); // Fatal Error
$myclass->MyPrivate(); // Fatal Error
$myclass->Foo(); // Public, Protected and Private work


/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// This is public
function Foo2()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate(); // Fatal Error
}
}

$myclass2 = new MyClass2;
$myclass2->MyPublic(); // Works
$myclass2->Foo2(); // Public and Protected work, not 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
?>

Видливост на константи

Од PHP 7.1.0, константите на класата може да бидат дефинирани како јавни, приватни или заштитени. Константите декларирани без експлицитен клуч збор за видливост се дефинирани како јавни.

Пример #6 Декларација на константа од PHP 7.1.0

<?php
/**
* Define MyClass
*/
class MyClass
{
// Declare a public constant
public const MY_PUBLIC = 'public';

// Declare a protected constant
protected const MY_PROTECTED = 'protected';

// Declare a private constant
private const MY_PRIVATE = 'private';

public function
foo()
{
echo
self::MY_PUBLIC;
echo
self::MY_PROTECTED;
echo
self::MY_PRIVATE;
}
}

$myclass = new MyClass();
MyClass::MY_PUBLIC; // Works
MyClass::MY_PROTECTED; // Fatal Error
MyClass::MY_PRIVATE; // Fatal Error
$myclass->foo(); // Public, Protected and Private work


/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// This is public
function foo2()
{
echo
self::MY_PUBLIC;
echo
self::MY_PROTECTED;
echo
self::MY_PRIVATE; // Fatal Error
}
}

$myclass2 = new MyClass2;
echo
MyClass2::MY_PUBLIC; // Works
$myclass2->foo2(); // Public and Protected work, not Private
?>

Видливост од други објекти

Објектите од ист тип ќе имаат пристап до приватните и заштитените членови едни на други, дури и ако не се исти инстанци. Ова е затоа што специфичните детали за имплементацијата се веќе познати кога се внатре во тие објекти.

Пример #7 Пристап до приватни членови од ист тип на објект

<?php
class Test
{
private
$foo;

public function
__construct($foo)
{
$this->foo = $foo;
}

private function
bar()
{
echo
'Accessed the private method.';
}

public function
baz(Test $other)
{
// We can change the private property:
$other->foo = 'hello';
var_dump($other->foo);

// We can also call the private method:
$other->bar();
}
}

$test = new Test('test');

$test->baz(new Test('other'));
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

string(5) "hello"
Accessed the private method.

Белешки од корисници 6 белешки

pgl на yoyo точка org
пред 10 години
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;
}
?>
Видливоста на својство, метод или (од PHP 7.1.0) константа може да се дефинира со додавање на клучните зборови пред декларацијата
пред 18 години
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
?>
jc точка flash на gmail точка com
пред 13 години
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
?>
alperenberatdurmus на gmail точка com
пред 2 години
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"
?>
bishop на php точка net
пред 9 години
> 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.
kostya на eltexsoft точка com
пред 4 години
I see we can redeclare private properties into child class 
<?php   
 class A{
        private int $private_prop = 4;
        protected int $protected_prop = 8;
    }

    class B 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
}
?>
На оваа страница

Автоматски outline од активната документација.

Насловите ќе се појават тука по вчитување.

Попрегледно читање

Примерите, changelog табелите и user notes се визуелно издвоени за да не се губат во долгата содржина.

Брз совет Користи го outline-от Скокни директно на главните секции од активната страница.
Извор Оригиналниот линк останува достапен Кога ти треба целосен upstream context, отвори го PHP.net во нов tab.