Vlastnosti pouze pro čtení v OOP v PHP

Pojďme se podívat na třídu, ve které jsou všechny vlastnosti soukromé:

Test.php<?php
  class Test
  {
    private $prop1 = 1;
    private $prop2 = 2;
  }
?>

Nyní uděláme tak, aby tyto vlastnosti ve vnějším světě byly dostupné pouze pro čtení. Podobné jsme již dělali dříve, když jsme vytvářeli gettery pro každou vlastnost a nevytvářeli settery.

Pojďme nyní k řešení tohoto úkolu využít kouzelnou metodu __get. Budeme v ní vracet hodnotu požadované vlastnosti. Jak to udělat: jméno požadované vlastnosti se dostane do parametru metody __get, v našem případě $property.

To znamená, že můžeme přečíst vlastnost, jejíž jméno je uloženo v proměnné, takto: $this->$property (jméno vlastnosti bude proměnná, tedy s dolarem na začátku, to jsme probírali v předchozích lekcích).

Pojďme vytvořit popsanou metodu __get:

Test.php<?php
  class Test
  {
    private $prop1 = 1;
    private $prop2 = 2;
    
    public function __get($property)
    {
      return $this->$property;
    }
  }
?>

Použijme ji pro čtení vlastností:

index.php<?php
  $test = new Test;
  
  echo $test->prop1; // vypíše 1
  echo $test->prop2; // vypíše 2
?>

Pokus o zápis něčeho do vlastnosti povede k chybě:

php<?php
  $test = new Test;
  $test->prop1 = 2; // vypíše chybu
?>

To je přesně to, co potřebujeme: vlastnost lze číst, ale nelze do ní zapisovat.

Pokus o přečtení neexistující vlastnosti vypíše chybu:

php<?php
  $test = new Test;
  echo $test->prop3; // vypíše chybu
?>

Všimněte si také následující nuance: když jsme dělali vlastnosti pouze pro čtení starým způsobem, tak pro to, abychom přečetli vlastnost, jsme používali metodu-getter.

V novém způsobu budeme přistupovat přímo k vlastnostem, jako by byly veřejné. Ale zapisovat do nich nebudeme moci, jako by byly soukromé.

Задание 1

Nechť je dána následující třída User, jejíž vlastnosti jsou dostupné pouze pro čtení pomocí getterů:

php<?php
  class User
  {
    private $name;
    private $age;
    
    public function __construct($name, $age)
    {
      $this->name = $name;
      $this->age = $age;
    }
    
    public function getName()
    {
      return $this->name;
    }
    
    public function getAge()
    {
      return $this->age;
    }
  }
?>

Přepište kód této třídy tak, aby místo getterů byl použit kouzelná metoda __get.