Kontynuujemy zabawy z MVC i klasami abstrakcyjnymi oraz dziedziczeniem. Tym razem poznamy słówko kluczowe parent i wyjdziemy na wyższy poziom, jeżeli chodzi o obiektówkę. Do dzieła!
Nasz plik helloname.php:
<?php
echo "<h1>Hello name page</h1>";
echo "<br>";
echo @"Hello $name";
Możemy już „zdjąć” error suppress operator – nie będzie nam potrzebny.
Klasa z poprzedniej lekcji:
<?php
abstract class InvokableController {
protected $path;
public function __construct($path)
{
$this->path = $path;
}
abstract public function __invoke();
}
class HomeController extends InvokableController {
public function __invoke(){
require __DIR__ . "/$this->path.php";
}
}
$invokable = new HomeController("helloname");
$invokable();
Tutaj jak widać pola klasy (path) oraz sam konstruktor znajdują się w abstrakcyjnej klasie bazowej, jedynie implementacja abstrakcyjnej metody invoke znajduje się w klasie pochodnej.
Tym razem nieco zamieszamy. Potrzebujemy dwóch dodatkowych pól w klasie pochodnej:
<?php
abstract class InvokableController {
protected $path;
public function __construct($path)
{
$this->path = $path;
}
abstract public function __invoke();
}
class HomeController extends InvokableController {
protected $code;
protected $data;
//(...)
}
$invokable = new HomeController("helloname", ['name' => 'John'], 200);
$invokable();
Chcemy, aby działało tak, jak to przedstawiłem w kodzie powyżej. Problem polega na tym, że konstruktor klasy głównej i abstrakcyjnej nie przewiduje takich pól.
Musimy zatem napisać własny, wywołać konstruktor bazowej za pomocą słówka kluczowego parent, następnie dodać nowe pola, których klasa bazowa nie przewiduje:
<?php
abstract class InvokableController {
protected $path;
public function __construct($path)
{
$this->path = $path;
}
abstract public function __invoke();
}
class HomeController extends InvokableController {
protected $code;
protected $data;
public function __construct($path, $data, $code=200)
{
parent::__construct($path);
$this->data = $data;
$this->code = $code;
}
//(...)
}
$invokable = new HomeController("helloname", ['name' => 'John'], 200);
$invokable();
Teraz możemy użyć naszego code i data w metodzie invoke:
<?php
abstract class InvokableController {
protected $path;
public function __construct($path)
{
$this->path = $path;
}
abstract public function __invoke();
}
class HomeController extends InvokableController {
protected $code;
protected $data;
public function __construct($path, $data, $code=200)
{
parent::__construct($path);
$this->data = $data;
$this->code = $code;
}
public function __invoke(){
http_response_code($this->code);
extract($this->data);
require __DIR__ . "/$this->path.php";
}
}
$invokable = new HomeController("helloname", ['name' => 'John'], 200);
$invokable();