2013-04-02 12 views
5

Szukałem, ale nie mogłem znaleźć ostatecznej odpowiedzi (jeśli istnieje) na używanie $ this w klasie PHP. Nadal staram się owijać głowę za pomocą metody OOP i chcę się upewnić, że używam najlepszych praktyk.Członkowie i metody klasy PHP

Więc moje pytanie dotyczy tego, w jaki sposób i kiedy powinieneś zdefiniować vary i kiedy powinieneś użyć $ this, aby je odnieść.

że mam następujące klasy ....

class Foo { 

private $pin; 
private $stat; 

public function get_stat($pin) { 
      $this->stat = shell_exec("blah read $pin"); 
      return $this->stat; 
    } 
} 

Więc w powyższej funkcji, mam var $ przekazany do metody klasy pin. Działa to dobrze, bez konieczności korzystania z $ this-> pin ... jednak poniższy kod wydaje się bardziej jak jest to dobry sposób, żeby zrobić to samo .....

class Foo { 

private $pin = 0; 
private $stat = 0; 

public function get_stat($pin) { 
      $this->pin = $pin; 
      $this->stat = shell_exec("blah read $this->pin"); 
      return $this->stat; 
    } 
} 

Również mam ustawić $ pin i $ stat vars to = 0. Domyślam się, że może to być wartość domyślna lub mogę zdefiniować je tak, jak w pierwszym przykładzie private $ pin; i prywatne statystyki $ ;.

Wracając do mojego pytania, jakie są najlepsze praktyki dotyczące używania członków i $ this w metodach klasowych? Jakie byłyby zalety lub wady każdego z przykładów?

+1

Mam dość dobrą odpowiedź na ten temat na [codereview.stackexchange] (http://codereview.stackexchange.com/). Sprawdź to [tutaj] (http://codereview.stackexchange.com/a/23857/20878) – jnthnjns

+0

Dzięki za link ASOK! Teraz ma sens, dlaczego powinieneś używać tylko $ this ... do odwoływania się do właściwości w klasie. Nie mogłem zrozumieć związku z dostępem do nich poza klasą. – user2233942

+0

Proszę NIGDY nie wywoływać powłoki z wartością bez zmian! 'shell_exec (" bla czytaj $ pin ");' jest szeroko otwarte na wstrzykiwanie kodu. Zawsze używaj funkcji wychodzących, w tym przypadku w przypadku poleceń powłoki: escapeshellarg() – Sven

Odpowiedz

6

Musisz użyć $ this, używając dowolnego członka klasy. Nie wolno jej używać podczas korzystania ze zmiennych lokalnych. Powinieneś unikać używania członków klasy, jeśli nie są ci potrzebni, np. $this->pin w twoim drugim przykładzie.

+0

dzięki Sven. Krótko mówiąc, jedyny moment, w którym mogę użyć $ this, to kiedy muszę pracować z członkiem klasy. Po prostu nie jest to potrzebne inaczej? – user2233942

+0

Nie nazwałbym tego "nie jest potrzebna". '$ this' nie może być używane podczas pracy z lokalnymi vars. – Sven

+0

Należy unikać używania zmiennych bezpośrednio w ciągach znaków ... –

-1

Jeśli chcesz trzymać się dobrych praktyk w OOP, powinieneś naprawdę mieć settery i moduły pobierające dla zmiennych instancji. Na przykład, tutaj jest zmiana kodu:

class Foo { 

    // common practice to begin private variables and methods with an underscore 
    private $_pin = 0; 
    private $_stat = 0; 

    // this is called a setter because we are setting a value 
    // note the lack of a return 
    public function setStat($stat) { 
     // we use $this-> because we are referencing THIS instance of THIS class/object 
     // and in doing so we refer to our private $_stat instance variable. 
     $this->_stat = $stat; 
    } 

    // this is called a getter because we are getting a value 
    // not how we are NOT setting values here. 
    public function getStat() { 
     return $this->_stat; 
    } 

} 

Więc ogólnie rzecz biorąc, należy użyć $this gdy odnoszą się do to wystąpienie klasy (nazywany również przedmiot). Zaletą posiadania klasy jest to, że możesz mieć wiele obiektów zdefiniowanych przez klasę. Na przykład:

class Person { 

    public $name, $age, $gender; 

    public function setName($name) { 
     $this->name = $name; 
    } 
    public function setAge($age) { 
     $this->age = $age; 
    } 
    public function setGender($gender) { 
     $this->gender = $gender; 
    } 
    public function getName() { 
     return $this->name; 
    } 
    public function getAge() { 
     return $this->age; 
    } 
    public function getGender() { 
     return $this->gender; 
    } 

} 

// outside the class 
$john = new Person(); 
$john->setName('John Doe'); 
$john->setAge(22); 
$john->setGender('male'); 
var_dump($john); 

var_dump pokaże:

object(Person)#1 (3) { 
    ["name"]=> string(8) "John Doe" // $this->name 
    ["age"]=> int(22)    // $this->age 
    ["gender"]=> string(4) "male" // $this->gender 
} 

nadzieję, że to pomaga!

+0

Nie, przepraszam, nie zgadzam się. Twój przykład gettera/ustawiającego dla "getStat" jest całkowicie błędny. Twój kod to nieskończona pętla z funkcją getStat() wywołującą getStat(), a pomysł jest nieprawidłowy. Dobrze jest mieć obiekt z metodami, które robią coś z przekazanymi parametrami i zwracają wynik. Twój drugi przykład to zupełnie inny przykład, ponieważ ilustrujesz programy pobierające/ustawiające z pamięcią wartości bez żadnych wewnętrznych funkcji. – Sven

+0

Dziękuję za podzielenie się swoją opinią. – djthoms

+0

Cóż, nieskończona pętla w 'getStat()' nadal tam jest, bez względu na moją opinię na temat reszty twojego kodu. – Sven

1

"najlepsza praktyka" zależy od Twoich potrzeb. W twoim przykładzie wygląda na to, że pin jest statyczny. Możesz po prostu ustawić to na początku, a nawet nie przekazać go do metody.

private $pin = 'abc123'; 

public function get_stat() { 
    $this->stat = shell_exec("blah read $this->pin"); 
    return $this->stat; 
} 

Ustawienie zmiennych klas ma sens tylko wtedy, gdy są one potrzebne, dzięki metodom w klasie. W twoim przykładzie zarówno klucz, jak i stat mogą być potencjalnie używane w wielu metodach, więc sensowne jest definiowanie ich jako zmiennych klasowych i uzyskiwanie do nich dostępu za pomocą $this->key ijest logiczne i logiczne. Nie miałoby sensu, gdyby coś takiego jak stat zostało użyte tylko w określonej metodzie lub zmienione w zależności od określonego zestawu danych, czyniąc stat atrybutem wielu obiektów zamiast wspólnego atrybutu klasy.

Jak zauważył Sven, użycie $this->pin, gdy $pin jest przekazywane do klasy, nie jest prawidłowe. Bardziej logiczne byłoby przypisanie go jako zmiennej klasy i użycie numeru $this->pin, jeśli pinezka nie ulegnie zmianie i jest wspólne dla instancji, w takim przypadku nie trzeba niczego przekazywać do metody.Podobnie jak na przykład żądanie API, w którym klucz prawdopodobnie się nie zmieni. Przekazanie $key dla metody ma sens, jeśli $key może być dowolne, jak wyniki z bazy danych, dane wejściowe użytkownika lub cokolwiek innego, jeśli źródło nie jest znane.

Nie wiem, czy to bardzo pomoże, ale tutaj jest przykład użycia modułów pobierających i ustawiających, jeśli zamierza się zmieniać wartości szpilki lub statystyki na podstawie dowolnego przekazanego w sposób ogólny lub abstrakcyjny. Getter and Setter?

+0

To było naprawdę pomocne Kai. Jak zauważyłeś i Sven, $ ten-> pin nie jest potrzebny, ponieważ jest przekazywany do klasy na początek. Moje rozłączenie jest relacją między var wewnątrz i na zewnątrz klasy (która nie wydaje się być żadną). – user2233942

0

Nigdy nie używaj var. Jest to przestarzała forma publiczna. Unikaj używania publicznych na swoich nieruchomościach, chcesz mieć kontrolę nad wartością każdej nieruchomości w klasie.