2013-03-12 16 views
7

Ostatnio zwiększam swoją grę PHP. Pochodząc z JavaScriptu, odkryłem, że model obiektu jest nieco prostszy do zrozumienia.Dostęp do własności PHP i znak dolara

Wpadłem w kilka dziwactw, które chciałem wyjaśnić, czego nie mogę znaleźć w dokumentacji.

Podczas definiowania klas w PHP, możesz zdefiniować właściwości tak:

class myClass { 

    public $myProp = "myProp"; 
    static $anotherProp = "anotherProp"; 

} 

ze zmienną publiczną $myProp możemy do niego dostęp za pomocą (zakładając myClass jest wymieniony w zmiennej o nazwie $myClass) $myClass->myProp bez użycia znaku dolara.

Możemy uzyskać dostęp do zmiennych statycznych za pomocą ::. Tak więc możemy uzyskać dostęp do zmiennej statycznej, takiej jak $myClass::$anotherProp ze znakiem dolara.

Pytanie brzmi, dlaczego musimy używać znaku dolara z ::, a nie ->?

EDIT

Jest to kod Przypuszczam będzie działać (i robi):

class SethensClass { 

    static public $SethensProp = "This is my prop!"; 

} 

$myClass = new SethensClass; 
echo $myClass::$SethensProp; 
+1

Interesujące ... Jedna próba i jedna bliska prośba. – Sethen

+0

Przepraszamy za komentarze tutaj [inne twoje pytanie] (http://stackoverflow.com/q/17681253/20578) (które, jeśli zostanie zadane jako seria indywidualnych pytań, ja osobiście uważałem, że byłoby dobrze - zobacz np. Http: //stackoverflow.com/questions/15270843/what-does-plus-operator-mean-in-underscore-js), ale powiedzenie czegoś takiego jak "najlepsza praktyka mówi, aby to zrobić" jest nieco bezsensowne. Jeśli nie potrafisz wytłumaczyć, * dlaczego * uważasz, że coś jest "najlepszą praktyką", to skąd wiesz, że jest "najlepsza"? Różne rzeczy są najlepsze w różnych sytuacjach. –

+0

@ PaulD.Waite W porządku. Jako programista starający się posunąć naprzód swój rozwój, zadając pytania o to, czy dana biblioteka przestrzega najlepszych praktyk, aby pomóc im się uczyć, jest w moim mniemaniu do przyjęcia. Dla całej społeczności brak wsparcia, co jest bardzo frustrujące. Nie wierzę, że konkretna biblioteka została napisana przy użyciu sprawdzonych metod i staram się upewnić, że jest to coś, czego nie robię źle, więc kiedy dodam kod, mogę być pewny, że jest najlepszy. – Sethen

Odpowiedz

14

class constant jest dostępne z operatorem zakresu :: i żaden znak dolara, więc $ jest tam potrzebny do rozróżnienia klas statycznych od stałych klas.

class myClass { 
    public static $staticProp = "static property"; 

    const CLASS_CONSTANT = 'a constant'; 
} 

echo myClass::CLASS_CONSTANT; 
echo myClass::$staticProp; 

Aby uzyskać dostęp do zmiennej, niezbędny jest $. Jednak $ nie można umieścić na początku nazwy klasy, na przykład $myClass::staticProp, ponieważ wtedy nazwa klasy nie może zostać zidentyfikowana przez analizator składni, ponieważ możliwe jest również użycie zmiennej jako nazwy klasy. Dlatego musi być dołączony do nieruchomości.

$myClass = "SomeClassName"; 
// This attempts to access a constant called staticProp 
// in a class called "SomeClassName" 
echo $myClass::staticProp; 

// Really, we need 
echo myClass::$staticProp; 
+0

+1 bicie mnie do tego –

+0

'$ myClass' ma reprezentować' $ myClass = new myClass'. – Sethen

+0

To nie ma sensu. $ staticProp jest zmienną klasy, a nie instancji, dlatego nie może być wywołana przez instancję klasy. –

0

jego Chciwy!

Czasami przydatne jest odwoływanie się do funkcji i zmiennych w klasach bazowych lub odnoszenie się do funkcji w klasach, które nie mają jeszcze żadnych instancji. Używany jest do tego :: operator.

<?php 
class A 
{ 
    function example() 
    { 
     echo "I am the original function A::example().<br>\n"; 
    } 
} 

class B extends A 
{ 
    function example() 
    { 
     echo "I am the redefined function B::example().<br>\n"; 
     A::example(); 
    } 
} 

// there is no object of class A. 
// this will print 
// I am the original function A::example().<br> 
A::example(); 

// create an object of class B. 
$b = new B; 

// this will print 
// I am the redefined function B::example().<br> 
// I am the original function A::example().<br> 
$b->example(); 
?> 

Powyższy przykład wywołuje przykład function() w klasie A, ale nie ma żadnego obiektu klasy A, tak, że nie możemy napisać $ a-> przyklad() lub podobny. Zamiast tego wywołujemy przykład() jako "funkcję klasy", to znaczy jako funkcję samej klasy, a nie jakiegokolwiek obiektu tej klasy.

Istnieją funkcje klasowe, ale nie ma zmiennych klasowych. W rzeczywistości nie ma żadnego obiektu w momencie połączenia. Zatem funkcja klasy nie może używać żadnych zmiennych obiektowych (ale może używać zmiennych lokalnych i globalnych) i nie może w ogóle używać $ this.

W powyższym przykładzie klasa B przedefiniowuje funkcję function(). Oryginalna definicja w klasie A jest zacieniona i nie jest już dostępna, chyba że chodzi konkretnie o implementację przykładu() w klasie A za pomocą operatora :: -.Napisz A :: example(), aby to zrobić (w rzeczywistości powinieneś pisać parent :: example()).

W tym kontekście istnieje bieżący obiekt i może mieć zmienne obiektowe. Tak więc, gdy użyjemy funkcji WITHIN funkcji object, możemy użyć zmiennej $ this i object.

Powiązane problemy