Posiada cztery sygnatury metod które musimy uzbroić w implementacje:
- offsetExists(mixed $offset) : bool
- Tutaj sprawdzamy czy klucz array'ki do którego próbujemy się odwołać w ogóle istnieje,
- offsetGet(mixed $offset) : mixed
- Zwracamy pożądany klucz array'a. Na wypadek gdy takowy nie istnieje warto zwrócić null,
- offsetSet(mixed $offset ,mixed $value) : void
- Służy do dodawania nowego klucza do array'a. Pierwszy parametr definiuje klucz array'a do którego wstawimy wartość którą reprezentuje drugi parametr,
- offsetUnset(mixed $offset) : void
- Tutaj musimy zaimplementować działanie kasowania wartości array'a.
Warto nadmienić, że implementując ten interfejs do naszej klasy, jej instancji nie będziemy mogli:
- trawersować w pętli foreach() - do tego jest np. interfejs Iterator,
- przekazanie takiego obiektu w następujący sposób: foreach($arrayAccessObject as $value) {...} sprawi, że pętla nie wykona się ani razu,
- 'policzyć ilości' elementów array'a w funkcji count() czy sizeof() - aby to osiągnąć klasa musi implementować interfejs Countable
- wywołanie funkcji count($arrayAccessObject) gdzie przekazana instancja będzie umożliwiała dostęp np. do trzech kluczy tablicy: $arrayAccessObject['name']; $arrayAccessObject['age']; $arrayAccessObject['email'] i tak zwróci wartość (int) 1.
- sprawdzać czy klucz istnieje za pomocą funkcji array_key_exists(). Ponieważ implementowana funkcja offsetExists() i tak nie zostanie automatycznie uruchomiona. To samo tyczy się w zasadzie każdej funkcji array'owej jak np. array_diff() czy array_push() - to po prostu nie zadziała.
co nie jest żadnym problemem gdy dysponujemy zwykłą tablicą.
Przykładowa implementacja:
class Person implements ArrayAccess {
/**
* @var string
*/
private $name;
/**
* @var int
*/
private $age;
/**
* @var string
*/
private $email;
public function __construct(
string $name,
int $age,
string $email
) {
$this->name = $name;
$this->age = $age;
$this->email = $email;
}
/**
* @inheritdoc
*/
public function offsetSet($propertyName, $propertyValue) {
$this->{$propertyName} = $propertyValue;
}
/**
* @inheritdoc
*/
public function offsetExists($propertyName) {
return property_exists($this, $propertyName);
}
/**
* @inheritdoc
*/
public function offsetUnset($propertyName) {
unset($this->{$propertyName});
}
/**
* @inheritdoc
*/
public function offsetGet($propertyName) {
return property_exists($this, $propertyName)
? $this->{$propertyName} : null;
}
}
$person = new Person('John', 30, 'john@gmail.com');
$person['lastName'] = 'Smith';
echo $person['lastName']; // Smith
Ciekawostki:
- Interfejs jest wykorzystywany w klasie SplObjectStorage.
- jeżeli zapewnimy odpowiednią obsługę to jako kluczy (w klasie klienta) będziemy mogli użyć np. obiektów, a nie tylko string'ów i integer'ów.
- jeśli koniecznie chcemy korzystać z funkcji array'owych to możemy zwracać całą array'kę z klasy implementującej ArrayAccess Interface poprzez jakąś metodę bądź - trochę wygodniejsze rozwiązanie z perspektywy klas klienckich - za pomocą metody magicznej __invoke(), wyglądało by to wtedy mniej więcej tak:
- array_push($arrayAccessObject(), 'newValue');
Brak komentarzy:
Prześlij komentarz