класс — Динамические методы в переполнении стека

Я нашел способ сделать следующий вызов с использованием динамических методов в PHP (input и img — просто пример, это может создать что угодно):

$Form->insert->input(array('type' => 'text', 'name' => 'firstName', 'maxlength' => '100', 'value' => 'First name'))
$Form->insert->img(array('id' => 'banner', 'src' => '/images/banner.svg'))

Этот трюк использует два объекта (Form и FormInsert). И Form insert использует метод _call, что означает, что я мог создать любой объект HTML с этим методом.

Хотя это работает хорошо, мне было интересно, есть ли способ использовать следующий, более хороший синтаксис вместо этого:

$Form->insert->input->type('text')->name('firstName')->maxlength('100')->value('First name')
$Form->insert->img->id('banner')->src('/images/banner.svg')

Идея заключалась бы в том, чтобы создать не просто входные данные, а какой-либо элемент HTML.

0

Решение

То, что вы спрашиваете, является обычной практикой в ​​jQuery, и вы наверняка можете сделать это на PHP, все, что вам нужно сделать, это возвращать объект каждый раз:

class FormInsert
{
...

public function __call( $method, $args )
{
// do the cool stuff

return $this;
}
...
}

Таким образом, вы вернетесь к FomrInput Объект для добавления сведений о теге, который вы строите.


Идея звучит интересно. Я вижу там несколько проблем, если вы ограничитесь двумя классами. Мне кажется, что FormInsert класс будет огромен и полон элементов управления, чтобы иметь дело с конкретными случаями и «синтаксисом HTML-тега».

Если я думаю о способах решения этих проблем, я получаю класс для каждого тега HTML, и мне не нужен магический метод. __call()… опять же, я не углубился в проблему.

1

Другие решения

Это может быть полезно для других, но мне удалось получить следующие 3 класса, которые могут помочь семантически создавать объекты HTML в PHP, отслеживая некоторую информацию, которая может быть повторно использована в PHP (например, идентификаторы внутри объекта или «имена» в форме). Следующий объект предназначен для формы, но может использоваться и для объекта body.

class ElementAttribute {

protected $parent; // Parent class object

function __construct(&$parent, $element) {
$this->parent = &$parent;

$this->rootElement = &$this->parent;
if (@is_object($this->rootElement->parent)) {
$this->rootElement = &$this->rootElement->parent; // Set root element
}
$this->rootClassName = strtolower(get_class($this->rootElement)); // Set root class name object
$this->element = $element; // Define current HTML element
$this->s = '<'.$this->element; // Initialize HTML string
}

public function __call($method, $args) {

$method = strtolower($method); // User lowercase by convention for HTML5

if (isset($args[0])) {
// Add available attributes to root element when created
if ($this->element == $this->rootClassName) {
if (@property_exists($this->rootElement, $method)) {
$this->rootElement->$method = $args[0];
}
}
// Add available attribute arrays to root element when created
$a = $method.'s';
if (@property_exists($this->rootElement, $a)) {
array_push($this->rootElement->$a, $args[0]);
}
$this->s .= ' '.$method.'="'.$args[0].'"';
}
return $this;
}

public function __toString() {
$s = $this->s.'>';
$m = $this->rootElement->lastUsedMethod;
unset($this->rootElement->$m); // Unset HTML object from root object so that a new object can replace it
return $s;
}
}

class HtmlElement {

protected $parent; // Parent class object

function __construct(&$parent) {
$this->parent = &$parent;
}

function __get($name) {
if (!@is_object($this->$name)) {
$this->$name = new ElementAttribute($this, $name);
}
return $this->$name;
}

}

class Form {

public $id; // Form Id
public $name = ''; // Form Name
public $ids = array(); // List of object Ids within the form
public $names = array(); // List of object Names within the form
public $lastUsedMethod; // Track last used dynamic method

function __get($name) {
if ($name == 'open') { // Open current HTML element tag
$this->$name = new ElementAttribute($this, get_class($this));
} else if ($name == 'insert') { // Insert new HTML element
$this->$name = new HtmlElement($this);
}
$this->lastUsedMethod = $name;
return $this->$name;
}

}

Некоторые примеры того, как его использовать:

$Form = new Form();

echo $Form->open->id('signup')->method('post')->autocomplete('off')->autocorrect('off')->action('/toto');

var_dump($Form);

echo $Form->insert->input->type('text')->name('firstName')->maxlength('100')->value('First name');

var_dump($Form);

echo $Form->insert->input->type('text')->name('lastName')->maxlength('100')->value('Last name');

var_dump($Form);
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector