Kontynuujemy przygodę z obiektówką języka PHP, klasami abstrakcyjnymi i wzorcem MVC. Tym razem poznajemy stałe klasowe. Do dzieła!

Nasz plik error.php:

<?php 
echo "<h1>{$code} - {$msg}</h1>";
die;

Piszemy klasę abstrakcyjną controller:

<?php 

abstract class Controller {

    protected $error_page;
    protected $home_page;

    const NOT_FOUND = 404;
    const UNAUTHORIZED = 403;
    const OK = 200;

}

Mamy tutaj pola, do których będziemy odnosić się poprzez this, oraz stałe, do których odnosimy się poprzez self.

Utwórzmy konstruktor w klasie bazowej bazując na polach:

<?php 

abstract class Controller {

    protected $error_page;
    protected $home_page;

    const NOT_FOUND = 404;
    const UNAUTHORIZED = 403;
    const OK = 200;

    public function __construct($error_page, $home_page)
    {
        $this->error_page = $error_page;
        $this->home_page = $home_page;
    }

}

Teraz metoda abstrakcyjna render oraz metoda z implementacją:

<?php 

abstract class Controller {

    //(...)

    abstract public function render($data);
    
    public function error($code, $data){
        http_response_code($code);
        extract($data);
        if(file_exists(__DIR__ . "/$this->error_page.php")){
            require __DIR__ ."/$this->error_page.php";
        } else {
            die($data["msg"]);
        }
    }

}

Nie ma tu nic, czego byśmy wcześniej nie robili. Pora na klasę pochodną:

abstract class Controller {

    protected $error_page;
    protected $home_page;

    const NOT_FOUND = 404;
    const UNAUTHORIZED = 403;
    const OK = 200;

    public function __construct($error_page, $home_page)
    {
        //(...)
    }

    abstract public function render($data);
    
    public function error($code, $data){
        //(...)
    }

}

class HomeController extends Controller {

    public function render($data) {
        
        if(file_exists(__DIR__ . "/$this->home_page.php")){
            http_response_code(self::OK);
            extract($data);
            require __DIR__ ."/$this->home_page.php";
        } else {
            parent::error(self::NOT_FOUND, ['msg' => 'not found', 'code' => self::NOT_FOUND]);
        }
    }
}

$controller = new HomeController("error", "home");
$controller->render(array());

Jak widać musieliśmy tylko zapewnić implementację metody abstrakcyjnej render.

Konstruktor – mamy w klasie bazowej. Metoda error – mamy implementację w klasie bazowej, odnosimy się do niej przez parent.

Do stałych klasowych (w klasie bazowej) odnosimy się poprzez słówko kluczowe self.

Jeżeli nie mamy pliku home.php, nasz kontroler wyrzuci nam 404 not found – tak ma być.