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

Hooks за имот

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

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

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

language.oop5.property-hooks.php

Hooks за имот

Проперти куките, познати и како „аксесори на проперти“ во некои други јазици, се начин за пресретнување и надминување на однесувањето при читање и запишување на проперти. Оваа функционалност служи две цели:

  1. Овозможува пропертите да се користат директно, без get- и set- методи, оставајќи ја отворена опцијата за додавање дополнително однесување во иднина. Тоа ги прави повеќето основни get/set методи непотребни, дури и без користење куки.
  2. Овозможува проперти кои опишуваат објект без потреба директно да складираат вредност.

Постојат две куки достапни на нестатични проперти: get and set. Тие овозможуваат надминување на однесувањето при читање и запишување на проперти, соодветно. Куките се достапни и за типизирани и за нетипизирани проперти.

Проперти може да биде „поддржан“ или „виртуелен“. Поддржан проперти е оној што всушност складира вредност. Секој проперти што нема куки е поддржан. Виртуелен проперти е оној што има куки и тие куки не комуницираат директно со самиот проперти. Во овој случај, куките се ефективно исти како методи, а објектот не користи простор за складирање вредност за тој проперти.

Проперти куките се некомпатибилни со readonly проперти. Ако постои потреба да се ограничи пристапот до get or set операција покрај менувањето на нејзиното однесување, користете асиметрична видливост на проперти.

Забелешка: Информации за верзија
Проперти куките беа воведени во PHP 8.4.

Основен синтакс на куки

Општиот синтакс за декларирање кука е како што следува.

Пример #1 Проперти куки (целосна верзија)

<?php
class Example
{
private
bool $modified = false;

public
string $foo = 'default value' {
get {
if (
$this->modified) {
return
$this->foo . ' (modified)';
}
return
$this->foo;
}
set(string $value) {
$this->foo = strtolower($value);
$this->modified = true;
}
}
}

$example = new Example();
$example->foo = 'changed';
print
$example->foo;
?>

На $foo проперти завршува со {}, наместо со точка и запирка. Тоа укажува на присуство на куки. Дефинирани се и get and set кука, иако е дозволено да се дефинира само едната или другата. Двете куки имаат тело, означено со {}, кое може да содржи произволен код.

На set куката дополнително овозможува специфицирање на типот и името на дојдовната вредност, користејќи го истиот синтакс како метод. Типот мора да биде ист како типот на пропертито, или contravariant (поширок) на него. На пример, својство од тип string може да има set кука што прифаќа string|Serializable, но не и таква што прифаќа само array.

Барем една од куките упатува на $this->foo, самото својство. Тоа значи дека својството ќе биде „поддржано“. При повикување на $example->foo = 'changed', дадениот стринг прво ќе се претвори во мали букви, а потоа ќе се зачува во поддржаната вредност. При читање од својството, претходно зачуваната вредност може условно да се надополни со дополнителен текст.

Постојат и неколку варијанти на кратка синтакса за справување со вообичаени случаи.

Ако get куката е единствен израз, тогаш {} може да се изостави и да се замени со израз со стрелка.

Пример #2 Израз за добивање својство

Овој пример е еквивалентен на претходниот.

<?php
class Example
{
private
bool $modified = false;

public
string $foo = 'default value' {
get => $this->foo . ($this->modified ? ' (modified)' : '');

set(string $value) {
$this->foo = strtolower($value);
$this->modified = true;
}
}
}
?>

Ако set тип на параметарот на куката е ист како типот на својството (што е типично), тој може да се изостави. Во тој случај, вредноста што треба да се постави автоматски се добива со името $value.

Пример #3 Поставки за добивање својство

Овој пример е еквивалентен на претходниот.

<?php
class Example
{
private
bool $modified = false;

public
string $foo = 'default value' {
get => $this->foo . ($this->modified ? ' (modified)' : '');

set {
$this->foo = strtolower($value);
$this->modified = true;
}
}
}
?>

Ако set куката само поставува изменета верзија на дадената вредност, тогаш таа исто така може да се поедностави до израз со стрелка. Вредноста што ја проценува изразот ќе се постави на поддржаната вредност.

Пример #4 Израз за поставување својство

<?php
class Example
{
private
bool $modified = false;

public
string $foo = 'default value' {
get => $this->foo . ($this->modified ? ' (modified)' : '');
set => strtolower($value);
}
}
?>

Овој пример не е сосема еквивалентен на претходниот, бидејќи не го менува и $this->modified. Ако се потребни повеќе изрази во телото на куката за поставување, користете ја верзијата со загради.

Својството може да имплементира нула, една или двете куки според потребите. Сите кратки верзии се меѓусебно независни. Тоа значи дека користењето кратка-добивка со долга-поставка, или кратка-поставка со експлицитен тип, или слично е сè валидно.

На имот со поддршка, изоставувањето на get or set кука значи дека ќе се користи стандардното однесување за читање или запишување.

Забелешка: Куките може да се дефинираат при користење промоција на својства на конструкторот. Сепак, при правењето на тоа, вредностите обезбедени на конструкторот мора да одговараат на типот поврзан со својството, без оглед на тоа што set куката може да дозволи. Размислете го следново:

<?php
class Example
{
public function
__construct(
public private(
set) DateTimeInterface $created {
set (string|DateTimeInterface $value) {
if (
is_string($value)) {
$value = new DateTimeImmutable($value);
}
$this->created = $value;
}
},
) {
}
}
Внатрешно, моторот го разложува ова на следново:
<?php
class Example
{
public private(
set) DateTimeInterface $created {
set (string|DateTimeInterface $value) {
if (
is_string($value)) {
$value = new DateTimeImmutable($value);
}
$this->created = $value;
}
}

public function
__construct(
DateTimeInterface $created,
) {
$this->created = $created;
}
}
Сите обиди за поставување на својството надвор од конструкторот ќе дозволат или string or DateTimeInterface вредности, но конструкторот ќе дозволи само DateTimeInterface.DateTimeInterfaceОва е затоа што дефинираниот тип за својството ( set ) се користи како тип на параметар во сигнатурата на конструкторот, без оглед на тоа што куката дозволува.

Ако ваков вид однесување е потребно од конструкторот, промоцијата на својства на конструкторот не може да се користи.

Виртуелни својства get nor set Виртуелните својства се својства кои немаат вредност за поддршка. Својството е виртуелно ако ниту неговото $foo куката се однесува на самото својство користејќи точна синтакса. Тоа е, својство именувано $this->foo чија кука содржи

ќе биде поддржано. Но следново не е поддржано својство и ќе предизвика грешка:

<?php
class Example
{
public
string $foo {
get {
$temp = __PROPERTY__;
return
$this->$temp; // Doesn't refer to $this->foo, so it doesn't count.
}
}
}
?>

For virtual properties, if a hook is omitted then that operation does not exist and trying to use it will produce an error. Virtual properties take up no memory space in an object. Virtual properties are suited for "derived" properties, such as those that are the combination of two other properties.

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

<?php
class Rectangle
{
// A virtual property.
public int $area {
get => $this->h * $this->w;
}

public function
__construct(public int $h, public int $w) {}
}

$s = new Rectangle(4, 5);
print
$s->area; // prints 20
$s->area = 30; // Error, as there is no set operation defined.
?>

Пример #6 Виртуелно својство get and set Дефинирање и на

кука на виртуелно својство е исто така дозволено.

Опсег

Сите куки работат во опсегот на објектот што се менува. Тоа значи дека тие имаат пристап до сите јавни, приватни или заштитени методи на објектот, како и до било кои јавни, приватни или заштитени својства, вклучувајќи ги и својствата што може да имаат свои куки за својства. Пристапувањето до друго својство од кука не ги заобиколува куките дефинирани на тоа својство.

Најзабележливата импликација на ова е дека нетривијалните куки може да повикаат до произволно сложен метод ако сакаат.

<?php
class Person {
public
string $phone {
set => $this->sanitizePhone($value);
}

private function
sanitizePhone(string $value): string {
$value = ltrim($value, '+');
$value = ltrim($value, '1');

if (!
preg_match('/\d\d\d\-\d\d\d\-\d\d\d\d/', $value)) {
throw new
\InvalidArgumentException();
}
return
$value;
}
}
?>

Пример #7 Повикување метод од кука

Референци $this->arrayProp['key'] = 'value';Бидејќи присуството на куки го пресретнува процесот на читање и запишување за својствата, тие предизвикуваат проблеми при стекнување референца до својство или при индиректно менување, како што е

. Тоа е затоа што секој обид за менување на вредноста по референца би ја заобиколил куката за запишување, ако е дефинирана. get Во реткиот случај кога е потребно добивање референца до својство што има дефинирани куки, & куката може да биде претставен со get and &get за да предизвика враќање по референца. Дефинирањето и на

на истото својство е синтаксна грешка. &get and set Дефинирањето и на set куки на поддржано својство не е дозволено. Како што е споменато погоре, запишувањето во вредноста вратена по референца би ја заобиколило

куката. На виртуелните својства, нема неопходна заедничка вредност помеѓу двете куки, така што дефинирањето и на двете е дозволено. &get Запишувањето во индекс на својство од тип низа исто така вклучува имплицитна референца. Од таа причина, запишувањето во поддржано својство од тип низа со дефинирани куки е дозволено ако и само ако дефинира само get or &get е законско, но дали тоа има какво било влијание врз објектот зависи од имплементацијата на куката.

Пребришувањето на целата ставка од низата е во ред и се однесува исто како и секоја друга ставка. Само работењето со елементи од низата бара посебно внимание.

Наследување

Конечни куки

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

Пример #8 Конечни куки

<?php
class User
{
public
string $username {
final
set => strtolower($value);
}
}

class
Manager extends User
{
public
string $username {
// This is allowed
get => strtoupper($this->username);

// But this is NOT allowed, because set is final in the parent.
set => strtoupper($value);
}
}
?>

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

Декларирањето на куки како конечни на ставка што е декларирана како конечна е излишно и ќе биде тивко игнорирано. Ова е истото однесување како и конечните методи.

Класата на дете може да дефинира или редефинира индивидуални куки на ставка со редефинирање на ставката и само куките што сака да ги пребрише. Класата на дете може исто така да додава куки на ставка што немала никакви. Ова е суштински исто како куките да биле методи.

Пример #9 Наследување на куки

<?php
class Point
{
public
int $x;
public
int $y;
}

class
PositivePoint extends Point
{
public
int $x {
set {
if (
$value < 0) {
throw new
\InvalidArgumentException('Too small');
}
$this->x = $value;
}
}
}
?>

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

Пристап до родителски куки

Кука во класата на дете може да пристапи до ставката на родителската класа користејќи го parent::$prop клучниот збор, проследен со посакуваната кука. На пример, parent::$propName::get(). Може да се прочита како „пристапи до prop декларирана на родителската класа, а потоа изврши нејзината операција за добивање“ (или операција за поставување, како што е соодветно).

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

Горниот пример може да се препише на следниов начин, што би овозможило Point За виртуелните својства, ако се изостави кука, тогаш таа операција не постои и обидот да се користи ќе предизвика грешка. Виртуелните својства не зафаќаат мемориски простор во објект. Виртуелните својства се погодни за „изведени“ својства, како што се оние што се комбинација на две други својства. set класа за да додаде своја

кука во иднина без проблеми (во претходниот пример, кука додадена на родителската класа би била игнорирана во детето).

<?php
class Point
{
public
int $x;
public
int $y;
}

class
PositivePoint extends Point
{
public
int $x {
set {
if (
$value < 0) {
throw new
\InvalidArgumentException('Too small');
}
parent::$x::set($value);
}
}
}
?>

Пример #10 Пристап до родителска кука (поставување)

Пример за преоптоварување само на get кука може да биде:

<?php
class Strings
{
public
string $val;
}

class
CaseFoldingStrings extends Strings
{
public
bool $uppercase = true;

public
string $val {
get => $this->uppercase
? strtoupper(parent::$val::get())
:
strtolower(parent::$val::get());
}
}
?>

Серијализација

Пример #11 Пристап до родителска кука (добивање)

  • var_dump()PHP има голем број различни начини на кои еден објект може да биде серијализиран, или за јавна употреба или за цели на дебагирање. Однесувањето на куките варира во зависност од случајот на употреба. Во некои случаи, ќе се користи суровата вредност на имотот, заобиколувајќи ги сите куки. Во други, имотот ќе се чита или пишува „преку“ куката, исто како и секое друго нормално дејство за читање/пишување.
  • serialize()PHP има голем број различни начини на кои еден објект може да биде серијализиран, или за јавна употреба или за цели на дебагирање. Однесувањето на куките варира во зависност од случајот на употреба. Во некои случаи, ќе се користи суровата вредност на имотот, заобиколувајќи ги сите куки. Во други, имотот ќе се чита или пишува „преку“ куката, исто како и секое друго нормално дејство за читање/пишување.
  • unserialize()PHP има голем број различни начини на кои еден објект може да биде серијализиран, или за јавна употреба или за цели на дебагирање. Однесувањето на куките варира во зависност од случајот на употреба. Во некои случаи, ќе се користи суровата вредност на имотот, заобиколувајќи ги сите куки. Во други, имотот ќе се чита или пишува „преку“ куката, исто како и секое друго нормално дејство за читање/пишување.
  • __serialize()/__unserialize(): Користи сурова вредност
  • : Прилагодена логика, користи get/set кука
  • var_export()Префрлање во низа: Користи сурова вредност
  • json_encode()Префрлање во низа: Користи сурова вредност
  • JsonSerializable: Користи get кука
  • get_object_vars()Префрлање во низа: Користи сурова вредност
  • get_mangled_object_vars()PHP има голем број различни начини на кои еден објект може да биде серијализиран, или за јавна употреба или за цели на дебагирање. Однесувањето на куките варира во зависност од случајот на употреба. Во некои случаи, ќе се користи суровата вредност на имотот, заобиколувајќи ги сите куки. Во други, имотот ќе се чита или пишува „преку“ куката, исто како и секое друго нормално дејство за читање/пишување.

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

: Прилагодена логика, користи get кука
1 месец пред
Examle #11 - access to parent hook
<?php

class Strings
{
    public string $val = 'parent val' {
        get => $this->val . ' parent hook';
    }
}

class CaseFoldingStrings extends Strings
{
    public bool $uppercase = true;

    public string $val = 'child val' {
        get => $this->uppercase
            ? strtoupper(parent::$val::get())
            : strtolower(parent::$val::get())
        ;
    }
}

$case = new CaseFoldingStrings;
var_dump($case->val); // CHILD VAL PARENT HOOK
На оваа страница

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

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

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

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

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