igorsimdyanov / php8

Примеры к книге "PHP 8. Котеров Д., Симдянов И."
65 stars 16 forks source link

Стр 618 - 625 #294

Open Cleverscript opened 7 months ago

Cleverscript commented 7 months ago

Пример с Redis не рабочий. При таком вызове в StaticPage

class StaticPage extends Cached
{
    // Конструктор класса
    public function __construct(protected ?int $id)
    {
        // Проверяем, нет ли такой страницы в кэше
        if ($this->isCached($this->id($id))) {
            // Есть, инициализируем объект содержимым кэша
            parent::__construct($this->title(), $this->content());

будет ошибка

Fatal error: Uncaught Error: Call to a member function get() on null in ...

потому что экземпляр Redis создается в конструкторе Cached, но ведь он не вызывается перед isCached if ($this->isCached($this->id($id))) {

из-за этого в методе get (класса Cached) нет объекта redis в $this->store

    // Извлечение значения $key из кэша
    protected function get($key)
    {
        return $this->store->get($key);
    }

https://disk.yandex.ru/i/p8uxrHI-uBnt5w

А если даже проинициализировать конструктор например так:

class StaticPage extends Cached
{
    // Конструктор класса
    public function __construct(protected ?int $id)
    {

        // Есть, инициализируем объект содержимым кэша
        parent::__construct();

        // Проверяем, нет ли такой страницы в кэше
        if ($this->isCached($this->id($id))) {

то все равно получаем ошибку, но уже из класса Page в методе render()

Fatal error: Uncaught Error: Typed property Page::$title must not be accessed before initialization in

https://disk.yandex.ru/i/OdYG09bUxY6anA

Что бы этой ошибки не было нужно в конструкторе Cached добавить parent::__construct($title, $content);

а в Page в конструкторе

$this->title = $title;
$this->content = $content;

Еще ошибка в условии в методе set класса Cached - пропущен восклицательный знак, из-за чего ключ никогда не добавится в кеш, правильный вариант такой:

    protected function set($key, $value, $force = false)
    {
        if ($force) {
           $this->store->set($key, $value, $this->expires);
        } else {
           if(!$this->isCached($key)) {
             $this->store->set($key, $value, $this->expires);
           }
        }
    }

Выложил работающий пример здесь https://github.com/Cleverscript/Polymorph_pages