Поскольку вы изучаете ООП, пришло время узнать о Abstract
классах (руководство по PHP) !
Абстрактный класс - это своего рода класс-скелет, который определяет серию универсальных функций. Абстрактный класс никогда не может быть создан (т. Е. Вы не можете вызвать new AbstractClass
), но может быть extend
отредактирован другими классами. Это позволяет нам определить что-то общее и повторяемое, скажем, и элемент HTML, а затем распространить его на конкретные элементы HTML с течением времени. Вот пример реализации этой концепции.
ВНИМАНИЕ: Я не говорю, что эта реализация - отличная идея; только в учебных целях!
Во-первых, некоторые абстрактные классы, чтобы определить, как этот материал должен работать.
abstract class HTMLWriter
{
protected $html = '';
protected $tagName = null;
protected $selfClosing = false;
protected $elements = array();
protected $attributes = array();
protected $closed = false;
abstract public function __construct();
public function addElement(HTMLWriter $element)
{
if ($this->closed || $this->selfClosing) {
return;
}
$element->close(); // automatic!
$this->elements[] = $element->write();
}
public function addElements() {
foreach (func_get_args() as $arg) {
if ($arg instanceof HTMLWriter) {
$this->addElement($arg);
}
}
}
public function addAttribute($name, $value)
{
return $this->attributes[$name] = $value;
}
public function write()
{
if (!$this->closed) {
$this->close();
}
return $this->html;
}
public function close()
{
$this->closed = true;
$this->html = '<' . $this->tagName;
foreach ($this->attributes AS $attr => $val) {
$this->html .= ' ' . $attr . '="' . $val . '"';
}
if ($this->selfClosing) {
$this->html .= '/>';
return;
}
$this->html .= '>';
foreach($this->elements as $elem) {
$this->html .= $elem;
}
$this->html .= '</' . $this->tagName . '>';
}
}
abstract class HTMLWriterWithTextNodes extends HTMLWriter
{
//abstract public function __construct();
public function addText($text)
{
$this->elements[] = htmlentities($text);
}
public function addTextRaw($text)
{
$this->elements[] = $text;
}
}
А затем конкретные реализации этих классов:
примечание: конкретный класс - это любой неабстрактный класс, хотя этот термин теряет свое значение при применении к классам, которые не являются расширениями абстрактных классов.
class Form extends HTMLWriter
{
public function __construct($action, $method, $can_upload = false)
{
$this->tagName = 'form';
$this->addAttribute('action', $action);
$this->addAttribute('method', $method);
if ($can_upload) {
$this->addAttribte('enctype','multipart/form-data');
}
}
}
class Input extends HTMLWriter
{
public function __construct($type, $name, $id = null)
{
$this->tagName = 'input';
$this->selfClosing = true;
$this->addAttribute('type', $type);
$this->addAttribute('name', $name);
if (!is_null($id)) {
$this->addAttribute('id', $id);
}
}
// overrides
public function addElement()
{
return false;
}
}
class Label extends HTMLWriterWithTextNodes
{
public function __construct($labelText = null, $for = null)
{
$this->tagName = 'label';
if (!is_null($labelText)) {
$this->elements[] = $labelText;
}
if (!is_null($for)) {
$this->addAttribute('for', $for);
}
}
}
class GenericElement extends HTMLWriterWithTextNodes
{
public function __construct($tagName, $selfClosing = false)
{
if (empty($tagName)) {
$this->closed = true;
$this->html = '';
return;
}
$this->tagName = $tagName;
$this->selfClosing = (bool)$selfClosing;
}
}
Наконец, давайте создадим и используем наши новые классы
$form = new Form('/class_lib.php','get');
$username = new Input('text','username','username');
$password = new Input('password','password','password');
$submit = new Input('submit','login');
$submit->addAttribute('value','login');
$ulabel = new Label('Username: ', 'username');
$plabel = new Label('Password: ','password');
$br = new GenericElement('br',true);
$form->addElements(
$ulabel, $username, $br,
$plabel, $password, $br,
$submit
);
echo $form->write();
Выход:
<form action="/class_lib.php" method="get"><label for="username">Username: </label><input type="text" name="username" id="username"/><br/><label for="password">Password: </label><input type="password" name="password" id="password"/><br/><input type="submit" name="login" value="login"/></form>
Ура для абстрактных классов!