通过PHP生成简单的HTML

通过PHP生成简单的HTML,php,html,Php,Html,我有一个HTML标记数组: class sampleHTML { public function __construct( $tag = [] ) { $html = [ [ 'type' => 'p', 'class' => '.sample-class', 'content' => 'Sample content'

我有一个HTML标记数组:

class sampleHTML {
    public function __construct( $tag = [] ) {
        $html = [
            [
                'type' => 'p',
                'class' => '.sample-class',
                'content' => 'Sample content'
            ],
            [
                'type' => 'div',
                'class' => '.sample-class-2',
                'content' => 'Sample content 2'
            ],
        ];

        foreach( $html as $tag ) {
            new Tag( $tag );
        }
    }
}
我想从数组中生成HTML。到目前为止,我有以下类来生成HTML

class Tag {

    public $tag;

    public function __construct( $tag = [] ) {
        $this->tag = $tag;

        switch ($tag['type']):
            case 'p':
                $this->render_p();
                break;
            case 'div':
                $this->render_div();
                break;
        endswitch;
    }

    private function render_p() {
        echo '<p class"' . $this->tag['class'] . '">' . $this->tag['content'] . '</p>';
    }

    private function render_div() {
        echo '<div class"' . $this->tag['class'] . '">' . $this->tag['content'] . '</div>';
    }

} 
class标签{
公共$标签;
公共函数_构造($tag=[])){
$this->tag=$tag;
开关($tag['type']):
案例“p”:
$this->render_p();
打破
案件‘div’:
$this->render_div();
打破
终端开关;
}
私有函数render_p(){
回显“

”.$this->tag['content'.[/p>”; } 私有函数render_div(){ 回显'.$this->标记['content'].'; } }

这没关系,但我想通过使用子类删除开关来改进代码。类似于以下内容:

class Tag {

    public $tag;

    public function __construct( $tag = [] ) {
        $this->tag = $tag;

        $this->render()
    }

    public function render() {};

}

class P extends Tag {
    public function render() {
        echo '<p class"' . $this->tag['class'] . '">' . $this->tag['content'] . '</p>';
    }
}

class Div extends Tag {
    public function render() {
        echo '<div class"' . $this->tag['class'] . '">' . $this->tag['content'] . '</div>';
    }
}
class标签{
公共$标签;
公共函数_构造($tag=[])){
$this->tag=$tag;
$this->render()
}
公共函数render(){};
}
类P扩展标记{
公共职能{
回显“

”.$this->tag['content'.[/p>”; } } 类Div扩展标记{ 公共职能{ 回显'.$this->标记['content'].'; } }

问题:

  • 是否可以使用不带开关的子类
  • 如果是,如何根据标记类型动态调用子类的
    render
    方法

  • 您可以使用
    new$var()
    创建动态实例,并移除开关

    foreach( $html as $tag ) {
       $class = ucfirst($tag['type']);
       $obj = new $class($tag); // will calls new P() or new Div()
       //$obj->render();
    }  
    
    完整代码:

    class sampleHTML {
        public function __construct() {
            $html = [
                [
                    'type' => 'p',
                    'class' => '.sample-class',
                    'content' => 'Sample content'
                ],
                [
                    'type' => 'div',
                    'class' => '.sample-class-2',
                    'content' => 'Sample content 2'
                ],
            ];
            foreach( $html as $tag ) {
                $class = ucfirst($tag['type']);
                new $class( $tag );
            }
        }
    }
    class Tag {
        public $tag;
        public function __construct( $tag = [] ) {
            $this->tag = $tag;
            $this->render();
        }
        public function render() {}
    }
    class P extends Tag {
        public function render() {
            echo '<p class="' . $this->tag['class'] . '">' . $this->tag['content'] . '</p>';
        }
    }
    class Div extends Tag {
        public function render() {
            echo '<div class="' . $this->tag['class'] . '">' . $this->tag['content'] . '</div>';
        }
    }
    new sampleHTML();
    
    classsamplehtml{
    公共函数构造(){
    $html=[
    [
    'type'=>'p',
    “类”=>“.示例类”,
    “内容”=>“示例内容”
    ],
    [
    'type'=>'div',
    'class'=>'。示例-class-2',
    “内容”=>“示例内容2”
    ],
    ];
    foreach($html作为$tag){
    $class=ucfirst($tag['type']);
    新$class($tag);
    }
    }
    }
    类标签{
    公共$标签;
    公共函数_构造($tag=[])){
    $this->tag=$tag;
    $this->render();
    }
    公共函数render(){}
    }
    类P扩展标记{
    公共职能{
    echo“

    ”.$this->tag['content'..

    ”; } } 类Div扩展标记{ 公共职能{ 回显'.$this->标记['content'].'; } } 新的sampleHTML();
    产出:

    <p class=".sample-class">Sample content</p><div class=".sample-class-2">Sample content 2</div>
    

    样本内容

    样本内容2
    首先,我认为为每种标记类型创建类是一种开销(直到它只是一个学习程序)

    基本上,您可以使用某种模式,如或

    所以我想说这样的话:

    interface TagInterface
    {
        public function render();
    }
    
    class TagFactory
    {
        public static function createTag($tag)
        {
            $class = ucfirst($tag['type']) . 'Tag';
            return new $class($tag);
        }
    }
    
    abstract class Tag implements TagInterface
    {
        protected $tag;
    
        public function __construct(array $tag)
        {
            $this->tag = $tag;
        }
    }
    
    class PTag extends Tag
    {
        public function render()
        {
            echo '<p class"' . $this->tag['class'] . '">' . $this->tag['content'] . '</p>';
        }
    }
    
    class DivTag extends Tag
    {
        public function render()
        {
            echo '<div class"' . $this->tag['class'] . '">' . $this->tag['content'] . '</div>';
        }
    }
    
    对于像您这样的任务,这是一个正确的体系结构。但是,我再说一遍,学习是可以的。在现实生活中,事情会简单得多,所以@Syscall的答案实际上是它应该看起来的样子

    是否可以使用不带开关的子类

    对!!您甚至可以在没有开关和子类的情况下执行此操作。
    您已经将标记类型设置为字符串,因此可以使用它:

    class Tag {
    
        public $tag;
    
        public function __construct( $tag = [] ) {
            $this->tag = $tag;
    
            $this->render();
        }
    
        private function render() {
            echo '<'.$this->tag['type'].' class"' . $this->tag['class'] . '">' . $this->tag['content'] . '</'.$this->tag['type'].'>';
        }
    } 
    
    编辑:

    如果您需要子类(因为有些标记是以完全不同的方式构建的),但仍然有一些基本标记,如
    p
    od
    div
    ,那么您可以仅为那些具有不同html的人定义覆盖
    render()
    -函数。如果它是带有标准html的标记,则可以在该子类中省去
    render()
    函数,这样它将使用标记类的
    render()
    函数。我编辑了上面的代码来表达这个想法。

    让我印象深刻的是,创建一个对象($tag的实例)并在构造函数中完成所有工作,然后取消引用该实例是编写program@symcbean如果可能的话,解释更多,并提供一个有效的方法的样本。谢谢它做的工作。也在寻找其他可能的解决方案。@user3631047我明白:)谢谢你的回复。谢谢。我在这里为我的问题写了一个简单的例子。我正在做一个表单生成器。有些字段有复杂的html,所以我需要将它们保存在单独的类中。我需要使用子类。我喜欢你解释的方式。谢谢。我编辑了我的答案,因为你说你确实需要子类。
    class Tag {
    
        public $tag;
    
        public function __construct( $tag = [] ) {
            $this->tag = $tag;
    
            $this->render();
        }
    
        private function render() {
            echo '<'.$this->tag['type'].' class"' . $this->tag['class'] . '">' . $this->tag['content'] . '</'.$this->tag['type'].'>';
        }
    } 
    
    class Tag {
        // constructor
    
        // render 
        function render(){
            // standard tag html
            echo '<'.$this->tag['type'].' class"' . $this->tag['class'] . '">' . $this->tag['content'] . '</'.$this->tag['type'].'>';
        }
    }
    
    class Table extends Tag {
        // render (this overrides the render function of Tag)
        function render(){
            echo '<table class"' . $this->tag['class'] . '"><th><td>Column 1</td><td>Column 2</td><td>Column 3</td></th><tbody></tbody></table>';
        }
    }
    
    class Div extends Tag {
        // no render function here
        // this way Div uses the render function of Tag 
    }