Теоретические задания | Практические задания
Именем класса может быть любое слово, которое не входит в список зарезервированных слов PHP, начинающееся с буквы или символа подчеркивания и за которым следует любое количество букв, цифр или символов подчеркивания.
<?php
class Publication
{
}
//bad practice
$publication = new Publication;
//best practice
$publication = new Publication();
?>
В контексте класса можно создать новый объект через new self и new parent.
<?php
class Publication
{
static public function getInstance()
{
return new self();
//return new static();
//return new parent();
}
}
?>
<?php
class Publication
{
//bad practice
var $title = 'Title';
//best practice
public $text = 'Text of the publication';
}
?>
<?php
$publication = new Publication();
echo $publication->title . \PHP_EOL;
echo $publication->text . \PHP_EOL;
?>
<?php
class Publication
{
public $title = 'Title';
protected $text = 'Text of the publication';
private $views = 0;
}
?>
<?php
$publication = new Publication();
echo $publication->title . \PHP_EOL;
// FATAL ERROR
echo $publication->text . \PHP_EOL;
// FATAL ERROR
echo $publication->views . \PHP_EOL;
?>
<?php
class Publication
{
public $title = 'Title';
protected $text = 'Text of the publication';
private $_views = 0;
//bad practice
function getTitle()
{
return $this->title;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getText()
{
return $this->text;
}
public function setText($text)
{
$this->text = $text;
}
public function getViews()
{
return $this->_views;
}
public function setViews($views)
{
$this->_views = $views;
}
}
?>
<?php
$publication = new Publication();
echo $publication->getTitle() . \PHP_EOL;
echo $publication->getText() . \PHP_EOL;
echo $publication->getViews() . \PHP_EOL;
?>
Что необходимо изменить в классе Publication?
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class Publication
{
/**
* @var string
*/
private $title = 'Title';
/**
* @var string
*/
private $text = 'Text of the publication';
/**
* @var integer
*/
private $views = 0;
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* @param string $text
*/
public function setText($text)
{
$this->text = $text;
}
/**
* @return integer
*/
public function getViews()
{
return $this->views;
}
/**
* @param integer $views
*/
public function setViews($views)
{
$this->views = $views;
}
}
?>
Как правильно добавить константу? Чем следующий пример плох?
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class Publication
{
/**
* @var string
*/
private $title = 'Title';
/**
* @var string
*/
private $text = 'Text of the publication';
/**
* @var integer
*/
private $views = 0;
//bad practice
const author = 'fightmaster';
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* @param string $text
*/
public function setText($text)
{
$this->text = $text;
}
/**
* @return integer
*/
public function getViews()
{
return $this->views;
}
/**
* @param integer $views
*/
public function setViews($views)
{
$this->views = $views;
}
}
?>
<?php
echo Publication::author . \PHP_EOL;
echo $publication::author . \PHP_EOL;
// FATAL ERROR
echo $publication->author . \PHP_EOL;
?>
Добавим конструктор с "тупым" комментарием
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class Publication
{
const AUTHOR = 'fightmaster';
/**
* @var string
*/
private $title = 'Title';
/**
* @var string
*/
private $text = 'Text of the publication';
/**
* @var integer
*/
private $views = 0;
/**
* @var \DateTime
*/
private $creationDate;
/**
* Constructor
*
* @todo remove stupid comment
*/
public function __construct()
{
$this->creationDate = new \DateTime('now');
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* @param string $text
*/
public function setText($text)
{
$this->text = $text;
}
/**
* @return integer
*/
public function getViews()
{
return $this->views;
}
/**
* @param integer $views
*/
public function setViews($views)
{
$this->views = $views;
}
}
?>
Изменение технического задания
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class News extends Publication
{
/**
* @var string
*/
private $author;
//такая запись конструктора в дочернем объекте эквивалентна ее отсутствию
public function __construct()
{
parent::__construct();
}
/**
* @return string
*/
public function getAuthor()
{
return $this->author;
}
/**
* @param string $author
*/
public function setAuthor($author)
{
$this->author = $author;
}
}
?>
<?php
$news = new News();
$news->setAuthor('admin');
echo $news->getAuthor() . \PHP_EOL;
?>
А что нужно изменить в объекте Publication?
getAuthor;
и setAuthor($author);
с поведением по умолчанию.<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class Publication
{
const AUTHOR = 'fightmaster';
/**
* @var string
*/
private $title = 'Title';
/**
* @var string
*/
private $text = 'Text of the publication';
/**
* @var integer
*/
private $views = 0;
/**
* @var \DateTime
*/
private $creationDate;
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* @param string $text
*/
public function setText($text)
{
$this->text = $text;
}
/**
* @return integer
*/
public function getViews()
{
return $this->views;
}
/**
* @param integer $views
*/
public function setViews($views)
{
$this->views = $views;
}
/**
* @return string
*/
public function getAuthor()
{
//return static::AUTHOR;
return self::AUTHOR;
}
/**
* @param string $author
*/
public function setAuthor($author)
{
}
}
?>
<?php
$publication = new Publication();
$publication->setAuthor('admin');
echo $publication->getAuthor() . \PHP_EOL;
?>
Изменение технического задания
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class Publication
{
const AUTHOR = 'fightmaster';
/**
* @var string
*/
private $title = 'Title';
/**
* @var string
*/
private $text = 'Text of the publication';
/**
* @var integer
*/
private $views = 0;
/**
* @var \DateTime
*/
private $creationDate;
/**
* @var string
*/
private $slug;
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
$this->generateSlug();
}
/**
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* @param string $text
*/
public function setText($text)
{
$this->text = $text;
}
/**
* @return integer
*/
public function getViews()
{
return $this->views;
}
/**
* @param integer $views
*/
public function setViews($views)
{
$this->views = $views;
}
/**
* @return string
*/
public function getAuthor()
{
//return static::AUTHOR;
return self::AUTHOR;
}
/**
* @param string $author
* @throws \Exception
*/
public function setAuthor($author)
{
throw \Exception(
sprintf('Unable sets author to the publication "%s".', $this->getTitle())
);
}
/**
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Generates slug based on Title
*/
private function generateSlug()
{
$this->slug = strtolower(str_replace(' ', '-', $this->getTitle()));
}
}
?>
<?php
$publication = new Publication();
$publication->setTitle('Test slug');
echo $publication->getSlug() . \PHP_EOL;
?>
Создадим интерфейс SignedInterface
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
interface SignedInterface
{
/**
* @return string
*/
function getAuthor();
/**
* @param string $author
*/
function setAuthor($author);
}
?>
Кто его будет имплементировать?
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class Publication implements SignedInterface
{
const AUTHOR = 'fightmaster';
/**
* @var string
*/
private $title = 'Title';
/**
* @var string
*/
private $text = 'Text of the publication';
/**
* @var integer
*/
private $views = 0;
/**
* @var \DateTime
*/
private $creationDate;
/**
* @var string
*/
private $slug;
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
$this->generateSlug();
}
/**
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* @param string $text
*/
public function setText($text)
{
$this->text = $text;
}
/**
* @return integer
*/
public function getViews()
{
return $this->views;
}
/**
* @param integer $views
*/
public function setViews($views)
{
$this->views = $views;
}
/**
* @return string
*/
public function getAuthor()
{
//return static::AUTHOR;
return self::AUTHOR;
}
/**
* @param string $author
* @throws \Exception
*/
public function setAuthor($author)
{
throw \Exception(
sprintf('Unable sets author to the publication "%s".', $this->getTitle())
);
}
/**
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Generates slug based on Title
*/
private function generateSlug()
{
$this->slug = strtolower(str_replace(' ', '-', $this->getTitle()));
}
}
?>
<?php
$publication = new Publication();
$news = new News();
if ($publication instanceof SignedInterface && $news instanceof SignedInterface) {
echo 'Классы реализовывают SignedInterface' . PHP_EOL;
}
?>
Изменение технического задания
Класс может быть объявлен, как абстрактный и не содержать абстрактных методов
Если класс имеет абстрактные методы, он обязан быть объялен как абстрактный
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
abstract class Publication implements SignedInterface
{
const AUTHOR = 'fightmaster';
/**
* @var string
*/
private $title = 'Title';
/**
* @var string
*/
private $text = 'Text of the publication';
/**
* @var integer
*/
private $views = 0;
/**
* @var \DateTime
*/
private $creationDate;
/**
* @var string
*/
private $slug;
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
$this->generateSlug();
}
/**
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* @param string $text
*/
public function setText($text)
{
$this->text = $text;
}
/**
* @return integer
*/
public function getViews()
{
return $this->views;
}
/**
* @param integer $views
*/
public function setViews($views)
{
$this->views = $views;
}
/**
* @return string
*/
public function getAuthor()
{
//return static::AUTHOR;
return self::AUTHOR;
}
/**
* @param string $author
* @throws \Exception
*/
public function setAuthor($author)
{
throw \Exception(
sprintf('Unable sets author to the publication "%s".', $this->getTitle())
);
}
/**
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Generates slug based on Title
*/
private function generateSlug()
{
$this->slug = strtolower(str_replace(' ', '-', $this->getTitle()));
}
}
?>
Добавим абстрактный метод getType()
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
abstract class Publication implements SignedInterface
{
const AUTHOR = 'fightmaster';
/**
* @var string
*/
private $title = 'Title';
/**
* @var string
*/
private $text = 'Text of the publication';
/**
* @var integer
*/
private $views = 0;
/**
* @var \DateTime
*/
private $creationDate;
/**
* @var string
*/
private $slug;
/**
* @return string
*/
abstract public function getType();
//abstract protected function getType();
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
$this->generateSlug();
}
/**
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* @param string $text
*/
public function setText($text)
{
$this->text = $text;
}
/**
* @return integer
*/
public function getViews()
{
return $this->views;
}
/**
* @param integer $views
*/
public function setViews($views)
{
$this->views = $views;
}
/**
* @return string
*/
public function getAuthor()
{
//return static::AUTHOR;
return self::AUTHOR;
}
/**
* @param string $author
* @throws \Exception
*/
public function setAuthor($author)
{
throw \Exception(
sprintf('Unable sets author to the publication "%s".', $this->getTitle())
);
}
/**
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Generates slug based on Title
*/
private function generateSlug()
{
$this->slug = strtolower(str_replace(' ', '-', $this->getTitle()));
}
}
?>
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class Article extends Publication
{
/**
* @return string
*/
public function getType()
{
return 'article';
}
}
?>
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class News extends Publication
{
/**
* @var string
*/
private $author;
/**
* @return string
*/
public function getType()
{
return 'news';
}
/**
* @return string
*/
public function getAuthor()
{
return $this->author;
}
/**
* @param string $author
*/
public function setAuthor($author)
{
$this->author = $author;
}
}
?>
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class Comment implements SignedInterface
{
/**
* @var string
*/
private $author;
/**
* @var string
*/
private $message;
/**
* @return string
*/
public function getAuthor()
{
return $this->author;
}
/**
* @param string $author
*/
public function setAuthor($author)
{
$this->author = $author;
}
/**
* @return string
*/
public function getMessage()
{
return $this->message;
}
/**
* @param string $message
*/
public function setMessage($message)
{
$this->message = $message;
}
}
?>
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
interface Commentable
{
/**
* @return Comment[]
*/
function getComments();
/**
* @param Comment $comment
*/
function addComment(Comment $comment);
}
?>
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class News extends Publication implements Commentable
{
/**
* @var string
*/
private $author;
/**
* Comment[]
*/
private $comments = array();
/**
* @return string
*/
public function getType()
{
return 'news';
}
/**
* @return string
*/
public function getAuthor()
{
return $this->author;
}
/**
* @param string $author
*/
public function setAuthor($author)
{
$this->author = $author;
}
/**
* @return Comment[]
*/
function getComments()
{
return $this->comments;
}
/**
* @param Comment $comment
*/
function addComment(Comment $comment)
{
$this->comments[] = $comment;
}
}
?>
<?php
$comment = new Comment();
$news = new News();
$news->addComment($comment);
var_dump($news->getComments());
?>
Добавим возможность хранить общее количество просмотров для всех статей и новостей.
view
setViews
<?php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
abstract class Publication implements SignedInterface
{
const AUTHOR = 'fightmaster';
private static $allViews = 0;
/**
* @var string
*/
private $title = 'Title';
/**
* @var string
*/
private $text = 'Text of the publication';
/**
* @var integer
*/
private $views = 0;
/**
* @var \DateTime
*/
private $creationDate;
/**
* @var string
*/
private $slug;
/**
* @return string
*/
abstract public function getType();
//abstract protected function getType();
public function view()
{
$this->views++;
self::$allViews++;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
$this->generateSlug();
}
/**
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* @param string $text
*/
public function setText($text)
{
$this->text = $text;
}
/**
* @return integer
*/
public function getViews()
{
return $this->views;
}
/**
* @return integer
*/
public function getAllViews()
{
return self::$allViews;
}
/**
* @return string
*/
public function getAuthor()
{
//return static::AUTHOR;
return self::AUTHOR;
}
/**
* @param string $author
* @throws \Exception
*/
public function setAuthor($author)
{
throw \Exception(
sprintf('Unable sets author to the publication "%s".', $this->getTitle())
);
}
/**
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Generates slug based on Title
*/
private function generateSlug()
{
$this->slug = strtolower(str_replace(' ', '-', $this->getTitle()));
}
}
?>
<?php
$article = new Article();
$comment = new Comment();
$news = new News();
$news->addComment($comment);
$news->view();
$news->view();
$article->view();
echo $news->getType() . ' views ' . $news->getViews() . PHP_EOL;
echo $article->getType() . ' views ' . $article->getViews() . PHP_EOL;
echo 'All views from ' . $news->getType() . ' ' . $news->getAllViews() . PHP_EOL;
echo 'All views from ' . $article->getType() . ' ' . $article->getAllViews() . PHP_EOL;
?>
*Что будет, если заменить self
на static
У аттрибута allViews
? *
Ключевое слово final
<?php
final class News
{
}
//fatal error
class BBCNews extends News
{
}
?>
Резервирование метода
php
<?php
abstract class Publication
{
/**
* Generates slug based on Title
*/
final private function generateSlug()
{
//code
}
}
?>
<?php
namespace BBC;
class News
{
}
?>
<?php
namespace Lenta;
class News
{
function strlen($string)
{
return \strlen($string);
}
}
?>
<?php
use BBC\News;
use Lenta\News as LentaNews;
$news = new News();
$news = new BBC\News();
$news = new \BBC\News();
$news = new LentaNews();
$news = new BC\News()
?>