Я нашел способ сделать следующий вызов с использованием динамических методов в 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.
То, что вы спрашиваете, является обычной практикой в jQuery, и вы наверняка можете сделать это на PHP, все, что вам нужно сделать, это возвращать объект каждый раз:
class FormInsert
{
...
public function __call( $method, $args )
{
// do the cool stuff
return $this;
}
...
}
Таким образом, вы вернетесь к FomrInput
Объект для добавления сведений о теге, который вы строите.
Идея звучит интересно. Я вижу там несколько проблем, если вы ограничитесь двумя классами. Мне кажется, что FormInsert
класс будет огромен и полон элементов управления, чтобы иметь дело с конкретными случаями и «синтаксисом HTML-тега».
Если я думаю о способах решения этих проблем, я получаю класс для каждого тега HTML, и мне не нужен магический метод. __call()
… опять же, я не углубился в проблему.
Это может быть полезно для других, но мне удалось получить следующие 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);