Zapis właściwości przez magię w OOP w PHP

Magiczna metoda __set jest wywoływana przy próbie zmiany wartości nieistniejącej lub ukrytej właściwości. Jako parametry przyjmuje nazwę właściwości i wartość, która jest jej próbowana przypisać.

Spójrzmy na praktycznym przykładzie. Załóżmy, że mamy taką klasę Test:

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

Stwórzmy w tej klasie magiczną metodę __set, która za pomocą funkcji var_dump będzie wyświetlać nazwę właściwości, do której nastąpiło odwołanie, i wartość, która jest tej właściwości próbowana ustawić:

Test.php<?php
  class Test
  {
    private $prop1;
    private $prop2;
    
    public function __set($property, $value)
    {
      var_dump($property . ' ' .$value);
    }
  }
?>

Sprawdźmy działanie naszej klasy:

index.php<?php
  $test = new Test;
  $test->prop = 'value'; // var_dump metody __set wyświetli 'prop value'
?>

Spróbujmy teraz ustawić wartość właściwości, której nazwa jest przechowywana w zmiennej $property:

Test.php<?php
  class Test
  {
    private $prop1;
    private $prop2;
    
    public function __set($property, $value)
    {
      $this->$property = $value; // ustawiamy wartość
    }
  }
?>

Teraz możemy zapisywać do właściwości prywatnych na zewnątrz klasy:

index.php<?php
  $test = new Test;
  
  $test->prop1 = 1; // zapiszemy 1
  $test->prop2 = 2; // zapiszemy 2
?>

Zapisywać możemy, jednak sprawdzić, czy coś się tam zapisało - nie, ponieważ właściwości są prywatne.

Można stworzyć getter dla tych właściwości lub po prostu skorzystać z magicznej metody __get. Skorzystajmy z drugiej opcji:

Test.php<?php
  class Test
  {
    private $prop1;
    private $prop2;
    
    public function __set($property, $value)
    {
      $this->$property = $value;
    }
    
    // Magiczny getter właściwości:
    public function __get($property)
    {
      return $this->$property;
    }
  }
?>

Dopiero teraz możemy sprawdzić działanie naszej klasy. Sprawdźmy:

index.php<?php
  $test = new Test;
  
  $test->prop1 = 1; // zapiszemy 1
  $test->prop2 = 2; // zapiszemy 2
  
  echo $test->prop1; // wyświetli 1
  echo $test->prop2; // wyświetli 2
?>

Oczywiście, tak naprawdę nie należy zezwalać wszystkim na zapisywanie do właściwości prywatnych, inaczej traci sens istnienia tych właściwości prywatnych (prościej zrobić je publicznymi i już).

Dlatego tę metodę należy stosować tylko wtedy, gdy jest to rzeczywiście konieczne. W kolejnych lekcjach rozważymy jeszcze przykłady udanego zastosowania.