mirror of
https://github.com/igorsimdyanov/php8.git
synced 2025-08-06 11:10:42 +00:00
Глава 30: наследование (черновик)
This commit is contained in:
15
inherit/anonym.php
Normal file
15
inherit/anonym.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
class Dumper
|
||||||
|
{
|
||||||
|
public static function print($obj)
|
||||||
|
{
|
||||||
|
print_r($obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dumper::print( new class {
|
||||||
|
public $title;
|
||||||
|
public function __construct(){
|
||||||
|
$this->title = 'Hello world!';
|
||||||
|
}
|
||||||
|
});
|
26
inherit/anonym_nested.php
Normal file
26
inherit/anonym_nested.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
class Container
|
||||||
|
{
|
||||||
|
private $title = 'Класс Container';
|
||||||
|
protected $id = 1;
|
||||||
|
public function anonym()
|
||||||
|
{
|
||||||
|
return new class($this->title) extends Container
|
||||||
|
{
|
||||||
|
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
public function __construct($title)
|
||||||
|
{
|
||||||
|
$this->name = $title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function print()
|
||||||
|
{
|
||||||
|
echo "{$this->name} ({$this->id})";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(new Container)->anonym()->print();
|
27
inherit/file/logger.php
Normal file
27
inherit/file/logger.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
class FileLogger
|
||||||
|
{
|
||||||
|
public $f; // открытый файл
|
||||||
|
public $name; // имя журнала
|
||||||
|
public $lines = []; // накапливаемые строки
|
||||||
|
public $t;
|
||||||
|
|
||||||
|
public function __construct($name, $fname)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
$this->f = fopen($fname, 'a+');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct()
|
||||||
|
{
|
||||||
|
fputs($this->f, join('', $this->lines));
|
||||||
|
fclose($this->f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function log($str)
|
||||||
|
{
|
||||||
|
$prefix = '[' . date('Y-m-d_h:i:s ') . "{$this->name}] ";
|
||||||
|
$str = preg_replace('/^/m', $prefix, rtrim($str));
|
||||||
|
$this->lines[] = $str . PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
31
inherit/file/logger/debug.php
Normal file
31
inherit/file/logger/debug.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
// Вначале подключаем "базовый" класс
|
||||||
|
require_once 'file/logger.php';
|
||||||
|
|
||||||
|
// Класс, добавляющий в FileLogger новую функциональность
|
||||||
|
class FileLoggerDebug extends FileLogger
|
||||||
|
{
|
||||||
|
// Конструктор нового класса. Просто переадресует вызов
|
||||||
|
// конструктору базового класса, передавая немного другие
|
||||||
|
// параметры.
|
||||||
|
public function __construct($fname)
|
||||||
|
{
|
||||||
|
// Такой синтаксис используется для вызова методов базового класса.
|
||||||
|
// Обратите внимание, что ссылки $this нет! Она подразумевается.
|
||||||
|
parent::__construct(basename($fname), $fname);
|
||||||
|
// Здесь можно проинициализировать другие свойства текущего
|
||||||
|
// класса, если они будут
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавляем новый метод
|
||||||
|
public function debug($s, $level = 0)
|
||||||
|
{
|
||||||
|
$stack = debug_backtrace();
|
||||||
|
$file = basename($stack[$level]['file']);
|
||||||
|
$line = $stack[$level]['line'];
|
||||||
|
// Вызываем функцию базового класса
|
||||||
|
$this->log("[at $file line $line] $s");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Все остальные методы и свойства наследуются автоматически!
|
||||||
|
}
|
32
inherit/file/logger/debug0.php
Normal file
32
inherit/file/logger/debug0.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
// Вначале подключаем "базовый" класс
|
||||||
|
require_once 'file/logger.php';
|
||||||
|
|
||||||
|
// Класс, добавляющий в FileLogger новую функциональность
|
||||||
|
class FileLoggerDebug0
|
||||||
|
{
|
||||||
|
// Объект "базового" класса FileLogger
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
// Конструктор нового класса. Создает объект FileLogger.
|
||||||
|
public function __construct($name, $fname)
|
||||||
|
{
|
||||||
|
$this->logger = new FileLogger($name, $fname);
|
||||||
|
// Здесь можно проинициализировать другие свойства текущего
|
||||||
|
// класса, если они будут
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавляем новый метод
|
||||||
|
public function debug($s, $level = 0)
|
||||||
|
{
|
||||||
|
$stack = debug_backtrace();
|
||||||
|
$file = basename($stack[$level]['file']);
|
||||||
|
$line = $stack[$level]['line'];
|
||||||
|
$this->logger->log("[at $file line $line] $s");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Оставляем на месте старый метод log()
|
||||||
|
public function log($s) { return $this->logger->log($s); }
|
||||||
|
// И такие методы-посредники мы должны создать ДЛЯ КАЖДОГО
|
||||||
|
// метода из FileLogger
|
||||||
|
}
|
9
inherit/final.php
Normal file
9
inherit/final.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
class Base
|
||||||
|
{
|
||||||
|
public final function test() {}
|
||||||
|
}
|
||||||
|
class Derive extends Base
|
||||||
|
{
|
||||||
|
public function test() {} // Ошибка! Нельзя переопределить!
|
||||||
|
}
|
6
inherit/inherit0.php
Normal file
6
inherit/inherit0.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'file/logger/debug0.php';
|
||||||
|
|
||||||
|
$logger = new FileLoggerDebug0('test', 'test.log');
|
||||||
|
$logger->log('Обычное сообщение');
|
||||||
|
$logger->debug('Отладочное сообщение');
|
14
inherit/inherit0cast.php
Normal file
14
inherit/inherit0cast.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'file/logger/debug0.php';
|
||||||
|
|
||||||
|
$logger = new FileLoggerDebug0('test', 'test.log');
|
||||||
|
|
||||||
|
// Казалось бы, все верно - все, что может FileLogger,
|
||||||
|
// 'умеет' и FileLoggerDebug0...
|
||||||
|
croak($logger, 'Hasta la vista.');
|
||||||
|
|
||||||
|
// Функция принимает параметр типа FileLogger
|
||||||
|
function croak(FileLogger $l, $msg) {
|
||||||
|
$l->log($msg);
|
||||||
|
exit();
|
||||||
|
}
|
21
inherit/inherit_static.php
Normal file
21
inherit/inherit_static.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
class Base
|
||||||
|
{
|
||||||
|
public static function title()
|
||||||
|
{
|
||||||
|
echo __CLASS__;
|
||||||
|
}
|
||||||
|
public static function test() {
|
||||||
|
self::title();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Child extends Base
|
||||||
|
{
|
||||||
|
public static function title()
|
||||||
|
{
|
||||||
|
echo __CLASS__;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Child::test(); // Base
|
75
inherit/pages/cached.php
Normal file
75
inherit/pages/cached.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'page.php';
|
||||||
|
|
||||||
|
class Cached extends Page
|
||||||
|
{
|
||||||
|
// Время действия кэша
|
||||||
|
protected $expires;
|
||||||
|
// Хранилище
|
||||||
|
protected $store;
|
||||||
|
|
||||||
|
// Конструктор класса
|
||||||
|
public function __construct($title = '', $content = '', $expires = 0)
|
||||||
|
{
|
||||||
|
// Вызываем конструктор базового класса Page
|
||||||
|
parent::__construct($title, $content);
|
||||||
|
// Устанавливаем время жизни кэша
|
||||||
|
$this->expires = $expires;
|
||||||
|
// Подготовка хранилища
|
||||||
|
// $this->store = new Memcached();
|
||||||
|
// $this->store->addServer('localhost', 11211);
|
||||||
|
// Размещение данных в хранилище
|
||||||
|
$this->set($this->id('title'), $title);
|
||||||
|
$this->set($this->id('content'), $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверить, есть ли позиция $key в кэше
|
||||||
|
protected function isCached($key)
|
||||||
|
{
|
||||||
|
// return (bool) $this->store->get($key);
|
||||||
|
}
|
||||||
|
// Поместить в кэш по ключу $key значение $value.
|
||||||
|
// В случае если ключ уже существует:
|
||||||
|
// 1. Не делать ничего, если $force принимает значение false.
|
||||||
|
// 2. Переписать, если $force принимает значение true.
|
||||||
|
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);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
// Извлечение значения $key из кэша
|
||||||
|
protected function get($key)
|
||||||
|
{
|
||||||
|
// return $this->store->get($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Формируем уникальный ключ для хранилища
|
||||||
|
public function id($name)
|
||||||
|
{
|
||||||
|
die('Что здесь делать? Неизвестно!');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение заголовка страницы
|
||||||
|
public function title()
|
||||||
|
{
|
||||||
|
// if ($this->isCached($this->id('title'))) {
|
||||||
|
// return $this->get($this->id('title'));
|
||||||
|
// } else {
|
||||||
|
return parent::title();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
// Получение содержимое страницы
|
||||||
|
public function content()
|
||||||
|
{
|
||||||
|
// if ($this->isCached($this->id('content'))) {
|
||||||
|
// return $this->get($this->id('content'));
|
||||||
|
// } else {
|
||||||
|
return parent::content();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
18
inherit/pages/cached_a.php
Normal file
18
inherit/pages/cached_a.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'page_a.php';
|
||||||
|
|
||||||
|
abstract class Cached extends Page
|
||||||
|
{
|
||||||
|
// Время действия кэша
|
||||||
|
protected $expires;
|
||||||
|
// Хранилище
|
||||||
|
protected $store;
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
// Формируем уникальный ключ для хранилища
|
||||||
|
abstract public function id($name);
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
}
|
10
inherit/pages/cast.php
Normal file
10
inherit/pages/cast.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'static_page.php';
|
||||||
|
|
||||||
|
function echoPage(Page $obj)
|
||||||
|
{
|
||||||
|
$obj->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
$shape = new StaticPage(3);
|
||||||
|
echoPage($shape);
|
14
inherit/pages/instanceof.php
Normal file
14
inherit/pages/instanceof.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'static_page.php';
|
||||||
|
|
||||||
|
function echoPage($obj)
|
||||||
|
{
|
||||||
|
$class = 'Page';
|
||||||
|
if (!($obj instanceof $class)) {
|
||||||
|
die("Argument 1 must be an instance of $class.<br />");
|
||||||
|
}
|
||||||
|
$obj->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
$page = new StaticPage(3);
|
||||||
|
echoPage($page);
|
30
inherit/pages/news.php
Normal file
30
inherit/pages/news.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'cached.php';
|
||||||
|
|
||||||
|
class StaticPage extends Cached
|
||||||
|
{
|
||||||
|
// Конструктор класса
|
||||||
|
public function __construct($id)
|
||||||
|
{
|
||||||
|
// Проверяем, нет ли такой страницы в кэше
|
||||||
|
if ($this->isCached($this->id($id))) {
|
||||||
|
// Есть, инициализируем объект содержимым кэша
|
||||||
|
parent::__construct($this->title(), $this->content());
|
||||||
|
} else {
|
||||||
|
// Данные пока не кэшированы, извлекаем
|
||||||
|
// содержимое из базы данных
|
||||||
|
// $query = "SELECT * FROM news WHERE id = :id LIMIT 1"
|
||||||
|
// $sth = $dbh->prepare($query);
|
||||||
|
// $sth = $dbh->execute($query, [$id]);
|
||||||
|
// $page = $sth->fetch(PDO::FETCH_ASSOC);
|
||||||
|
// parent::__construct($page['title'], $page['title']);
|
||||||
|
parent::__construct('Новости', 'Содержимое страницы Новости');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Уникальный ключ для кэша
|
||||||
|
public function id($name)
|
||||||
|
{
|
||||||
|
return "news_{$name}";
|
||||||
|
}
|
||||||
|
}
|
34
inherit/pages/page.php
Normal file
34
inherit/pages/page.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
class Page
|
||||||
|
{
|
||||||
|
// Любая страница имеет заголовок
|
||||||
|
protected $title;
|
||||||
|
// И содержимое
|
||||||
|
protected $content;
|
||||||
|
|
||||||
|
// Конструктор класса
|
||||||
|
public function __construct($title = '', $content = '')
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
$this->content = $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение заголовка страницы
|
||||||
|
public function title()
|
||||||
|
{
|
||||||
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение содержимого страницы
|
||||||
|
public function content()
|
||||||
|
{
|
||||||
|
return $this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Формирование HTML-представления страницы
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
echo '<h1>' . htmlspecialchars($this->title()) . '</h1>';
|
||||||
|
echo '</p>' . nl2br(htmlspecialchars($this->content())) . '</p>';
|
||||||
|
}
|
||||||
|
}
|
34
inherit/pages/page_a.php
Normal file
34
inherit/pages/page_a.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
abstract class Page
|
||||||
|
{
|
||||||
|
// Любая страница имеет заголовок
|
||||||
|
protected $title;
|
||||||
|
// И содержимое
|
||||||
|
protected $content;
|
||||||
|
|
||||||
|
// Конструктор класса
|
||||||
|
public function __construct($title = '', $content = '')
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
$this->content = $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение заголовка страницы
|
||||||
|
public function title()
|
||||||
|
{
|
||||||
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение содержимого страницы
|
||||||
|
public function content()
|
||||||
|
{
|
||||||
|
return $this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Формирование HTML-представления страницы
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
echo '<h1>' . htmlspecialchars($this->title()) . '</h1>';
|
||||||
|
echo '</p>' . nl2br(htmlspecialchars($this->content())) . '</p>';
|
||||||
|
}
|
||||||
|
}
|
30
inherit/pages/static_page.php
Normal file
30
inherit/pages/static_page.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'cached.php';
|
||||||
|
|
||||||
|
class StaticPage extends Cached
|
||||||
|
{
|
||||||
|
// Конструктор класса
|
||||||
|
public function __construct($id)
|
||||||
|
{
|
||||||
|
// Проверяем, нет ли такой страницы в кэше
|
||||||
|
if ($this->isCached($this->id($id))) {
|
||||||
|
// Есть, инициализируем объект содержимым кэша
|
||||||
|
parent::__construct($this->title(), $this->content());
|
||||||
|
} else {
|
||||||
|
// Данные пока не кэшированы, извлекаем
|
||||||
|
// содержимое из базы данных
|
||||||
|
// $query = "SELECT * FROM static_pages WHERE id = :id LIMIT 1"
|
||||||
|
// $sth = $dbh->prepare($query);
|
||||||
|
// $sth = $dbh->execute($query, [$id]);
|
||||||
|
// $page = $sth->fetch(PDO::FETCH_ASSOC);
|
||||||
|
// parent::__construct($page['title'], $page['title']);
|
||||||
|
parent::__construct('Контакты', 'Содержимое страницы Контакты');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Уникальный ключ для кэша
|
||||||
|
public function id($name)
|
||||||
|
{
|
||||||
|
return "static_page_{$id}";
|
||||||
|
}
|
||||||
|
}
|
7
inherit/pages/test.php
Normal file
7
inherit/pages/test.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'static_page.php';
|
||||||
|
|
||||||
|
$id = 3;
|
||||||
|
$page = new StaticPage($id);
|
||||||
|
$page->render();
|
||||||
|
echo $page->id($id);
|
22
inherit/static.php
Normal file
22
inherit/static.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
class Base
|
||||||
|
{
|
||||||
|
public static function title()
|
||||||
|
{
|
||||||
|
echo __CLASS__;
|
||||||
|
}
|
||||||
|
public static function test()
|
||||||
|
{
|
||||||
|
static::title();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Child extends Base
|
||||||
|
{
|
||||||
|
public static function title()
|
||||||
|
{
|
||||||
|
echo __CLASS__;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Child::test(); // Child
|
0
inherit/test.log
Normal file
0
inherit/test.log
Normal file
Reference in New Issue
Block a user