PHP protected property – co mi uniká?
- j.salak
- Člen | 42
Zdravím, toto není uplně nette, ale obecně PHP. Je toto správné chování přístupu k protected property? Pokud 2 třídy dědí jednu nadžezenou a přepošlu si potomka z jedné do druhé, jaktože můžu přistoupit k její protected property? Možná už sem jenom přepracovanej :) Potřeboval bych aby to možné nebylo, poradíte? Díky
class a
{
protected $aa = 1;
}
class b extends a
{
function foo()
{
$c = new c;
$c->foo($this);
}
}
class c extends a
{
function foo(b $b)
{
print_r($b->aa);
}
}
$b = new b;
$b->foo();
- Šaman
- Člen | 2666
Cožeco? Trochu se v tom ztrácím, protože to není naformátované, ale
dva potomci o sobě nic nevědí. Ledaže by dostali instanci toho druhého,
ale pak maji přístup jen k public
.
Protected
znamená, že potomek má přístup k property předka
(může s ní pracovat).
A private
znamená, že ani potomek nesmí sahat na property
definovanou v předkovi.
Edit: pokus o přeformátování
<?php
class a
{
protected $aa = 1;
}
class b extends a
{
function foo()
{
$c = new c;
$c->foo($this);
}
}
class c extends a
{
function foo(b $b)
{
print_r($b->aa);
}
}
$b = new b;
$b->foo();
?>
Tak ne, ten print_r
nebude fungovat. Potomek má přístup
do property předka (tedy $this->aa
) ale $b
je
cizí třída, tam vidí jen public
.
Edit: viz dále
Editoval Šaman (5. 4. 2016 23:55)
- David Matějka
- Moderator | 6445
@Šaman nemas pravdu :) https://3v4l.org/jI01O
@j.salak ano, je to tak. viz http://php.net/…sibility.php#… … modifikatory viditelnosti nemaji vliv na jen objekt, ale na celou tridu
- CZechBoY
- Člen | 3608
Moc dobře nechápu o co se snažíš. Pokud dědíš tu třídu A tak
všechny protected
budou vidět ve všech potomcích,
private
uvidí jen třída A.
Pokud potřebuješ property viditelnou pouze v B tak použij private – ale
nebude zase vidět v A.
Zkus se trošku prohrabat tím manuálem viditelnosti co poslal David M.
- Šaman
- Člen | 2666
Uff, co to je za podivnou medicínu? Ono to trochu vážně funguje.
Ale ne zas tak moc, abych se
na to chtěl spoléhat. (Tenhle druhý výsledek jsem ale očekával už od
začátku. Člověk se furt učí… :)
V každém případě sorry za dezinformaci.
Editoval Šaman (5. 4. 2016 23:48)
- Oli
- Člen | 1215
@Šaman, @DavidMatějka jestli mě něco neuniká, tak máte
pravdu oba. Tenhle příklad funguje protože, pokud neuvedeš modifikátor
viditelnosti, tak se metoda považuje za public. Protected
metodu foo
třída B skutečně nevidí…
EDIT:// Nic, až teď jsem si všiml, že se bavíme o property a ne o metodě… Jdu spát :-)
Editoval Oli (5. 4. 2016 23:39)
- j.salak
- Člen | 42
Takže to všem funguje, super :) každopádně potřebuju poradit jak udělat aby to nefungovalo, tzn. aby pořád byla tam $aa property zvenku nedostupná, protože na to mám navázané nějaké gettery a takhle mi je to nezavolá a vrací mí přímo obsah té property a to je pro mě nežádoucí.
Zkoušel jsem to volat i přes call_user_func() ale nepomohlo.
Zatím jediné čím to vypadá, že bych to mohl napravit, je opětovným nadefinováním protected $aa; v třídě „b“. Pak už se to chová přepokládaně, ale není to hezké.
Editoval j.salak (6. 4. 2016 10:16)
- David Matějka
- Moderator | 6445
každopádně potřebuju poradit jak udělat aby to nefungovalo, tzn. aby pořád byla tam $aa property zvenku nedostupná, protože na to mám navázané nějaké gettery
snadno to udelat nepujde :) pokud bys tu promennou aa potreboval jen v „a“ a ne v „b“ a „c“, tak ji muzes udelat private. A nemuzes ty gettery (jestli tim myslis metody) volat primo?
- j.salak
- Člen | 42
David Matějka napsal(a):
každopádně potřebuju poradit jak udělat aby to nefungovalo, tzn. aby pořád byla tam $aa property zvenku nedostupná, protože na to mám navázané nějaké gettery
snadno to udelat nepujde :) pokud bys tu promennou aa potreboval jen v „a“ a ne v „b“ a „c“, tak ji muzes udelat private. A nemuzes ty gettery (jestli tim myslis metody) volat primo?
Jojo, já předělám ten koncept, to neni problém, jen jsem myslel jestli není nějaká jednoduchá cesta jak to obejít abych do toho hotovýho nemusel šahat :) ale v pohodě, jen si na to musim dát do budoucna pozor. Díky za rady.
- j.salak
- Člen | 42
j.salak napsal(a):
David Matějka napsal(a):
každopádně potřebuju poradit jak udělat aby to nefungovalo, tzn. aby pořád byla tam $aa property zvenku nedostupná, protože na to mám navázané nějaké gettery
snadno to udelat nepujde :) pokud bys tu promennou aa potreboval jen v „a“ a ne v „b“ a „c“, tak ji muzes udelat private. A nemuzes ty gettery (jestli tim myslis metody) volat primo?
Jojo, já předělám ten koncept, to neni problém, jen jsem myslel jestli není nějaká jednoduchá cesta jak to obejít abych do toho hotovýho nemusel šahat :) ale v pohodě, jen si na to musim dát do budoucna pozor. Díky za rady.
Tak ono to tak jednoduchý nebude, protože i když bych to zjednodušil
<?php
class a
{
protected $aa = 1;
}
class b extends a
{
function foo()
{
$c = new c;
print_r($c->aa);
}
}
class c extends a
{
}
$b = new b;
$b->foo();
?>
tak stejně pořád můžu k tý protected property,l tak hold musim volat ty gettery (metody) přímo.
- Šaman
- Člen | 2666
To volání getterů přímo se mi osvědčilo skoro vždy. Výjimka je
v presenteru $this->template
, veškerá volání v šablonách
a v ORM entitách magické property (které jsou ale vždy zapsané
v anotacích).
Když jsem to zkoušel používat častěji, tak to vedlo k nekonzistenci
v kódu, sám jsem nevěděl, jestli volám metodu, nebo pravou property a po
nějaké době jsem si začal myslet, že ta property opravdu existuje. Teď už
i ostatní metody v presenteru raději volám getterem
($presenter->getUser()
).