PHP 8.2 - sprawdź co nowego!

Programowanie obiektowe > Lekcja 2

Właściwości i metody

Jak już wspomniałem, w każdej klasie możemy zdefiniować metody i właściwości tworzonych obiektów. Właściwość nazwałbym w uproszczeniu zmienną w tym obiekcie. Podobnie zresztą wygląda jej definicja - ze znakiem $ na początku. Możemy przypisać jej dowolną wartość, użyć jej w dowolnym miejscu tego obiektu i tak dalej. Zobaczmy jak takową zdefiniować:

<?php

class Car
{
    public $color;
}

Możemy też od razu przypisać jakąś wartość, na przykład:

<?php

class Car
{
    public $color = 'black';
}

php >=7.4 wprowadza określanie typu dla właściwości, podobnie jak ma to miejsce przy argumentach funkcji czy zwracanych danych. Wystarczy dodać go między public a nazwą. Dzięki temu mamy porządek, jasne określenie czym ma być dana wartość.

<?php

class Car
{
    public string $color = 'black';
}

W tym momencie wartość, którą będzie przechowywała ta właściwość, może być tylko stringiem. Przy próbie przypisania innego typu otrzymamy stosowny Fatal error. Typem argumentu czy wartości, oprócz znanych Ci standardowo typów, może być także wskazanie konkretnej klasy, jakiej obiekt przekażemy/zwrócimy - dotyczy to zarówno OOP, jak i samych funkcji. Od php >=8.0 także właściwość może mieć wiele typów, oddzielonych |.

Metody definiujemy równie prosto, przy użyciu słowa kluczowego function. Są to po prostu funkcje wykonywane na rzecz danego obiektu.

<?php

class Car
{
    public function getColor()
    {
        return 'black';
    }
}

Tak jak w zwykłych funkcjach, mamy możliwość przekazania argumentów. Znów, od php >=7 możemy określić ich typ oraz dodać typ zwracanej wartości, również identycznie jak przy funkcjach i także mogą to być te podstawowe typy albo konkretne klasy. php 8.0 lub wyższe umożliwi wskazanie wielu typów.

<?php

class Car
{
    public function getColor(string $text): string
    {
        return $text . 'black';
    }
}

Typ object

php 7.2 wprowadziło nowy typ object. Możemy nim określić, że argumentem/wartością zwróconą będzie jakiś obiekt, bez określenia jego klasy. Jednak tam, gdzie jest to możliwe, określałbym precyzyjnie o obiekcie jakiej klasy mowa.

Teraz tylko nasuwa się pytanie: jak dostać się do tej właściwości albo jak wywołać taką funkcję obiektu? To nic trudnego, służy nam do tego ->.

<?php

class Car
{
    public string $color = 'black';

    public function getColor(string $text): string
    {
        return $text . 'black';
    }
}

$car = new Car();
echo $car->color; //result: black
echo $car->getColor('Color: '); // result: Color: black

Co ważne, przy odwoływaniu się do właściwości nie używamy znaku dolara $!

Strzałka, a nie kropka

W innych językach programowania w celu odwołania do właściwości/metody obiektu często używany jest znak . (kropki). Jednak w PHP jest to tylko->. Kropka, jak pewnie pamiętasz, służy do łączenia ciągów.

Modyfikatory dostępu

Słowo public nie pojawia się wszędzie przypadkowo. Jest to modyfikator, który określa dostępność danego elementu. Wyróżniamy 3 modyfikatory:

  • public - właściwość lub metoda jest publiczna, będzie więc widoczna wszędzie: wewnątrz obiektu i poza nim.

    <?php
    
    class Car
    {
        public string $color = 'black';
    }
    
    $car = new Car();
    echo $car->color; // result: black
    
  • private - właściwość lub metoda jest prywatna, czyli może zostać użyta tylko wewnątrz danego obiektu. Będziemy mogli jej użyć na przykład w metodach definiowanych wewnątrz danego obiektu.

    <?php
    
    class Car
    {
        private string $color = 'black';
    }
    
    $car = new Car();
    echo $car->color; // result: fatal error
    

    Ciekawostka

    Dawno temu panowała zasada, że nazwy prywatnych właściwości rozpoczynało się od znaku _, na przykład $_color. Obecnie jednak już się tego nie stosuje, wspominam tylko przy okazji, aby taki zapis nie był dla Ciebie dziwny. W praktyce i tak nie zmienia to niczego w działaniu.

  • protected - podobnie jak w przypadku private, takiej właściwości/metody można użyć tylko w obiekcie, lecz dodatkowo można ją dziedziczyć oraz będzie widoczna w klasach dziedziczących. Czym jest i jak działa dziedziczenie, powiemy sobie w jednej z kolejnych lekcji, wtedy też przedstawię konkretny przykład działania tego modyfikatora.

Przy próbie odwołania się do elementu, do którego nie powinniśmy mieć dostępu, ujrzymy odpowiedni błąd, dla powyższego przykładu:

Fatal error: Uncaught Error: Cannot access private property Car::$color in ...

Brak modyfikatora?

Dla metod dopuszczalne jest również niepodanie żadnego modyfikatora i wtedy domyślnie nadany zostanie public. Jest to jednak praktyka niepolecana, gdyż zaciemnia kod. Po podaniu modyfikatora widać od razu, jaki jest i że ktoś umyślnie go tam wpisał.

Modyfikatory zostały stworzone, aby chronić pewne właściwości przed zmianą czy metody przed wywołaniem. Należy używać ich z rozwagą, rozpatrzyć każdy przypadek indywidualnie w trakcie pisania. Ogólnie panuje zasada, że co nie musi być widoczne dla wszystkich, takowe być nie powinno. Często mówi się, że dobrą praktyką jest nadawanie „automatycznie” wszystkiemu private i dopiero, jeśli widać potrzebę zmiany, należy o tym pomyśleć i to zrobić.

Właściwość tylko do odczytu

W php 8.1 wprowadzona została nowa opcja readonly, która umożliwia zdefiniowanie właściwości jako „tylko do odczytu”. W praktyce będziemy mogli nadać jej wartość jedynie raz, po inicjalizacji będzie się dało tylko odczytywać zawartość. Dzięki temu można przykładowo zdefiniować właściwość z modyfikatorem public bez obawy, że będzie ona w niekontrolowany sposób zmieniana.

Aby tego dokonać, wystarczy dopisać słowo kluczowe readonly po modyfikatorze dostępu. Trzeba jednak uwzględnić, że w taki sposób możemy oznaczyć tylko właściwość, która ma wskazany typ. Próba ponownego przypisania wartości dla takiej właściwości zakończy się błędem:

<?php

class Car
{
    public readonly string $color;
    
    public function setDefaultColor()
    {
        $this->color = 'black';
    }
    
    public function setOtherColor()
    {
        $this->color = 'red';
    }
}

$car = new Car();
$car->setDefaultColor();
$car->setOtherColor(); // Fatal error: Uncaught Error: Cannot modify readonly property Car::$color

Należy jednak pamiętać, że taka właściwość nie może mieć wartości domyślnej. Drugą ważną kwestią jest to, że ustawienia wartości możemy tylko z wnętrza klasy. Próba zrobienia tego z zewnątrz także spowoduje błąd.

Dodatkowo od php 8.2 możliwe jest oznaczenie całej klasy jako tylko do odczytu. W takiej sytuacji wszystkie jej właściwości będą się tak zachowywały. Analogicznie pamiętać trzeba, że wtedy wszystkie właściwości tej klasy muszą mieć nadany typ, w innej sytuacji wystąpi błąd.

<?php

readonly class Car
{
    // ...
}
Poprzednia lekcja Następna lekcja

Udostępnij

  • Facebook
  • Twitter

Komentarze