PHP中的动态方法

时间:2014-09-27 00:13:17

标签: php class object dynamic methods

我找到了一种在PHP中使用动态方法进行以下调用的方法(输入和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插入使用_call方法,这意味着我可以使用此方法创建任何HTML对象。

虽然效果很好,但我想知道是否有办法使用以下更好的语法?:

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

我们的想法是创建不仅仅是输入而是创建任何类型的HTML元素。

2 个答案:

答案 0 :(得分:1)

你问的是jQuery中的常见做法,你肯定可以在PHP中做到,你需要做的就是每次都返回对象:

class FormInsert
{
    ...

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

        return $this;
    }
    ...
}

这样您就可以回到FomrInput对象来添加有关正在构建的标记的详细信息。


这个想法听起来很有意思。如果你把自己限制在两个班级,我会看到一些问题。在我看来,FormInsert类将是巨大的并且充满了控制以处理特定情况和#34; HTML标记语法"。

如果我想到解决这些问题的方法,我最终会得到一个每个HTML标记的类,而不需要魔术方法__call() ...然后,我再也没有进入问题。

答案 1 :(得分:0)

这可能对其他人有用,但我设法得到以下3个类,这些类可以帮助在PHP中语义创建HTML对象,同时跟踪可以在PHP中重用的一些信息(例如对象中的ID或者名称中的'名称')形成)。以下对象适用于表单,但也可用于“正文”对象。

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);