PHP 类生成 HTML?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3488373/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 09:57:14  来源:igfitidea点击:

PHP Class to Generate HTML?

phphtml

提问by Howard Zoopaloopa

Anyone know of any classes written for php that can clean up your code a bit?

任何人都知道为 php 编写的任何类可以稍微清理您的代码?

Something like,

就像是,

$htGen = new HTMLGenerator();
$htGen->newDOM('div', 'here is what goes in the div', 'optionalID', 'optionalClass');

Or does that just sound redundant?

或者这听起来是多余的吗?

I end up with some complex looking mish-mashes of html and php sometimes that I feel could be simplified a bit eg my latest cms bit;

有时我会得到一些看起来很复杂的 html 和 php 大杂烩,我觉得可以稍微简化一下,例如我最新的 cms 位;

foreach($details as $detail){

    $d = unserialize($detail);

    if($ad){
        print_r($d); // <-- VIEW DETAIL OBJECT IN WHOLE.
    }else{
    if($d->get_info('orphan')){
        echo '<li class="classRow orphan">' . "\n";
        echo '<div class="orphan" style="display:none">orphan</div>' . "\n";
    }else{
        echo '<li class="classRow">' . "\n";
        echo '<div class="orphan" style="display:none"></div>' . "\n";
    }

        echo '<div  class="classNumbers" id="' . $d->get_info('class ID') .  '" style="display:none"></div>' . "\n"; 
        echo '<div class="rowBG" style="overflow:hidden;width:100%">';   
            echo '<div class="startTime"></div>' . "\n";
            echo '<div class="details"><span class="classes">' . $d->get_info('class number') . '</span> - <input class="detailInput" type="text" value="' . $d->get_info('class description') . '"/><div class="editButton"><a class="editExpand">options(+)</a></div></div>' . "\n";
            echo '<div class="interval">';
            echo '<input class="intervalInput" type="text" value="' . $d->get_info('interval') . '" maxlength="5"/>';
            echo '</div>' . "\n"; 
            echo '<div class="numRiders"><input class="numRidersInput" type="text" value="' . $d->get_info('num riders') . '"/></div>' . "\n"; 
        echo '</div>'; 

        echo '<div class="classOptions">' . "\n";
            echo '<div class="selectRingMove">Move to Ring:<select id="ringSwap"><option>Select A Ring</option>' . get_ring_options() .  '</select></div>' . "\n";
            if($d->get_info('online sign up') != 'false'){
                echo '<div class="signUpContainer">Sign-Up<input type="checkbox" class="signUp" checked/></div>' . "\n";
            }else{
                echo '<div class="signUpContainer">Sign-Up<input type="checkbox" class="signUp"/></div>' . "\n";
            }
            if($d->get_info('water and drag')){
                echo '<div class="wdBoxContainer"><select id="wdDescrip"><option>WATER AND DRAG</option><option>COURSE CHANGE & WALK</option><option>OTHER</option></select><input type="checkbox" class="wdBox" checked/><input type="text" value="' . $d->get_info('water and drag') .  '" maxlength="2" class="wdInput"> min</div>' . "\n";
            }else{
                echo '<div class="wdBoxContainer"><select id="wdDescrip"><option>WATER AND DRAG</option><option>COURSE CHANGE & WALK</option><option>OTHER</option></select><input type="checkbox" class="wdBox"/><input type="text" value="20" maxlength="2" class="wdInput"> min</div>' . "\n";
            }
            if($d->get_info('ghost riders')){
                echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" checked class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput" value="' . $d->get_info('ghost riders') .  '"></div>' . "\n";
            }else{
                echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput"></div>' . "\n";
            }

        echo '</div>' . "\n";

    echo '</li>' . "\n";

    if($d->get_info('water and drag')){
        echo '<li class="waterAndDragRow" style="display:block;"><span class="wdStartTime">08:33am</span> - <span class="wdEndTime">08:34am</span> <input type="text" class="wdDescription" value="' . $d->get_info('water and drag description') . '"></li>';
    }
    }
}

Or, if you know of a cleaner way to write long blocks of intermingled php vars and html... (not a big fan of EOF>>>)

或者,如果你知道一种更简洁的方法来编写混合的 php vars 和 html 的长块......(不是 EOF 的忠实粉丝>>>)

Thanks in advance.

提前致谢。

回答by Guido Hendriks

I guess it could be done with http://www.php.net/manual/en/class.domdocument.php. But that isn't really a good way to do it.

我想这可以通过http://www.php.net/manual/en/class.domdocument.php完成。但这真的不是一个好方法。

I agree that your code code sample isn't very clear, you could consider something like:

我同意您的代码示例不是很清楚,您可以考虑以下内容:

<ul>
<?php foreach ($items as $item): ?>
    <li>
        <?=$item['something']?>
        <?php if ($item['foo'] == 'bar'): ?>
        <ul>
            <li>bar</li>
        </ul>
        <?php else: ?>
        <ul>
            <li>foo</li>
        </ul>
        <?php endif; ?>
    </li>
<?php endforeach; ?>
<ul>

That's a lot better imho, I use it like that in my views.

恕我直言,这好多了,我在我的观点中就是这样使用它的。

Btw, you should validate your html output. For example, a div-element isn't allowed in a li-element.

顺便说一句,您应该验证您的 html 输出。例如,div-element 中不允许使用li-element。

edit: Obviously, the following code:

编辑:显然,以下代码:

<?php if ($item['foo'] == 'bar'): ?>
<ul>
    <li>bar</li>
</ul>
<?php else: ?>
<ul>
    <li>foo</li>
</ul>
<?php endif; ?>

Could be replaced by:

可以替换为:

<ul>
    <li><?=($item['foo'] == 'bar' ? 'bar' : 'foo')?></li>
</ul>

回答by Thank you

I'm working on a simple DSL that addresses this common task. It's called htmlgenand it's being hosted on Github.

我正在研究解决这个常见任务的简单 DSL。它被称为htmlgen,它托管在 Github 上。

I just pushed 2.xwith some major improvements.

我刚刚推出了一些重大改进的2.x。

Here's an example

这是一个例子

use function htmlgen\html as h;

h('#wrapper',
  h('h1.title', 'Hello, World'),
  h('p',
    h('comment', 'link to project'),
    h('a', ['href'=>'https://github.com/naomik/htmlgen'], 'See htmlgen on Github')
  )
);

Here's the output (actual output does not have whitespace)

这是输出(实际输出没有空格)

<div id="wrapper">
  <h1 class="title">Hello, World</h1>
  <p>
    <!-- link to project -->
    <a href="https://github.com/naomik/htmlgen">See htmlgen on Github</a>
  </p>
</div>

It's very new but at ~200 lines of source, it's already very powerful. Fork it and make adjustments or send me a note with suggestions.

它很新,但在大约 200 行的源代码中,它已经非常强大了。分叉它并进行调整或向我发送带有建议的便条。

回答by Your Common Sense

The main idea of generating HTML is to keep HTML as is.
Just divide your script into 2 parts: prepare data part and display data part. A latter one should contain mostly HTML with some PHP control structures. Of course, there should be as less PHP code as possible. Move all unnecessary PHP code into first part.

生成 HTML 的主要思想是保持 HTML 原样。
只需将您的脚本分为两部分:准备数据部分和显示数据部分。后一个应该主要包含带有一些 PHP 控制结构的 HTML。当然,PHP 代码应该越少越好。将所有不必要的 PHP 代码移到第一部分。

Well to sum up all of the above:
there should be nothing to unserialize in the $details array. Have your data prepared already

总结一下以上所有内容:
$details 数组中应该没有要反序列化的内容。已经准备好您的数据

<? foreach ($details as $d): ?>              
<li class="classRow orphan">
  <div class="orphan" style="display:none"><? if ($d->get_info('orphan')): ?>orphan<? endif ?></div>
   <div class="classNumbers" id="<?= $d->get_info('class ID') ?>" style="display:none"></div> 
    <div class="rowBG" style="overflow:hidden;width:100%">
     <div class="startTime"></div>
      <div class="details">
       <span class="classes"><?= $d->get_info('class number') ?></span> -
        <input class="detailInput" type="text" value="<?= $d->get_info('class description') ?>"/>
         <div class="editButton">
          <a class="editExpand">options(+)</a>
         </div>
        </div>
        <div class="interval">
         <input class="intervalInput" type="text" value="<?= $d->get_info('interval') ?>" maxlength="5"/>
        </div>
        <div class="numRiders">
         <input class="numRidersInput" type="text" value="<?= $d->get_info('num riders') ?>"/>
        </div>
       </div>
       <div class="classOptions">
       <div class="selectRingMove">Move to Ring:
        <select id="ringSwap">
         <option>Select A Ring</option>
<?= foreach (get_ring_options() as $value => $option): ?>
     <option value="<?=$value?>"><?=$option?></option>
<? endforeach ?>
         </select>
       </div>
       <div class="signUpContainer">Sign-Up
        <input type="checkbox" class="signUp" <? if (!$d->get_info('online sign up'): ?>checked<? endif ?>/>
       </div>

and so on.

等等。

The main rule should be DRY: Do not Repeat Yourself. Do not repeat blocks of code if there is only one word difference.
But enclose that word into condition

主要规则应该是 DRY:不要重复自己。如果只有一个单词差异,请不要重复代码块。
但是把这个词附在条件中

Note that get_ring_options() was replaced with proper code.
Do not make functions that return HTML, but an array instead.

请注意,get_ring_options() 已替换为正确的代码。
不要创建返回 HTML 的函数,而是创建一个数组。

回答by Kwebble

Instead of a class, consider a library of functions to generate HTML. I didn't use a class to make the code that you end up writing concise but expressive. With a class you must create an instance and use that variable, or make the methods static and write static references.

考虑一个函数库来生成 HTML,而不是一个类。我没有使用类来使您最终编写的代码简洁但富有表现力。对于类,您必须创建一个实例并使用该变量,或者将方法设为静态并编写静态引用。

With this technique creating HTML for an image that is a link looks like this:

使用此技术为链接图像创建 HTML 如下所示:

a('/example/url', img('image_url', $altText));

This is based on a script I once created. First the generic functions to generate HTML elements and attributes:

这是基于我曾经创建的脚本。首先是生成 HTML 元素和属性的通用函数:

function tag($tag, $text, $attributes = array()) {
    return "<$tag" . attributesToArray($attributes) . ">$text</$tag>";
}

function minimizedTag($tag, $attributes = array()) {
    return "<$tag" . attributesToArray($attributes) . " />";
}

function attributesToArray($attributes = array()){
    $a = '';
    foreach ($attributes as $attribute => $value) {
        $a .= " $attribute='$value'";
    }
    return $a;
}

Then add functions named according to the HTML elements they create, like a() and img() to create a link and image:

然后添加根据它们创建的 HTML 元素命名的函数,如 a() 和 img() 以创建链接和图像:

function a($link, $text, $attributes = array()) {
    $a = array('href' => $link);
    foreach ($attributes as $attribute => $value) {
        $a[$attribute] = $value;
    }
    return tag('a', $text, $a);
}

function img($url, $alt = null) {
    $a = array('src' => $url);
    if (!is_null($alt)){
        if (is_array($alt)){
            $a = array_merge($a, $alt);
        } else {
            $a['alt'] = $alt;
        }
    }
    return minimizedTag('img', $a);
}

Choose the parameters to pass common attributes wisely to make the library easier to use.

明智地选择参数以传递公共属性,使库更易于使用。

回答by John Kugelman

I'll probably get downvoted for recommending short tags, but here's what I do. I put all the <?and ?>tags at column 1 so that the code reads like a mix of PHP and HTML. No echostatements is the goal.

我可能会因为推荐短标签而被否决,但这就是我所做的。我将所有<??>标签放在第 1 列,这样代码读起来就像 PHP 和 HTML 的混合体。没有echo声明是目标。

    foreach ($details as $detail) {
        $d = unserialize($detail);

        if ($ad) {
            print_r($d); // <-- VIEW DETAIL OBJECT IN WHOLE.
        }
        else {
            if ($d->get_info('orphan')) {
?>              <li class="classRow orphan">
                  <div class="orphan" style="display:none">orphan</div>
<?          }
            else {
?>              <li class="classRow">
                  <div class="orphan" style="display:none"></div>
<?          }

?>          <div class="classNumbers" id="<?= $d->get_info('class ID') ?>"
                 style="display:none"></div> 
            <div class="rowBG" style="overflow:hidden;width:100%">
              <div class="startTime"></div>
              <div class="details">
                <span class="classes"><?= $d->get_info('class number') ?></span> -
                <input class="detailInput" type="text" value="<?= $d->get_info('class description') ?>"/>
                <div class="editButton">
                  <a class="editExpand">options(+)</a>
                </div>
              </div>
              <div class="interval">
                <input class="intervalInput" type="text" value="<?= $d->get_info('interval') ?>" maxlength="5"/>
              </div>
              <div class="numRiders">
                <input class="numRidersInput" type="text" value="<?= $d->get_info('num riders') ?>"/>
              </div>
            </div>

            <div class="classOptions">
              <div class="selectRingMove">
                Move to Ring:
                <select id="ringSwap">
                  <option>Select A Ring</option>
                  <?= get_ring_options() ?>
                </select>
              </div>

<?            if ($d->get_info('online sign up') != 'false') {
?>                <div class="signUpContainer">
                    Sign-Up
                    <input type="checkbox" class="signUp" checked/>
                  </div>
<?            }
              else {
?>                <div class="signUpContainer">
                    Sign-Up
                    <input type="checkbox" class="signUp"/>
                  </div>
<?            }

              if ($d->get_info('water and drag')) {
?>                <div class="wdBoxContainer">
                    <select id="wdDescrip">
                      <option>WATER AND DRAG</option>
                      <option>COURSE CHANGE &amp; WALK</option>
                      <option>OTHER</option>
                    </select>

                    <input type="checkbox" class="wdBox" checked/>
                    <input type="text" value="<?= $d->get_info('water and drag') ?>" maxlength="2" class="wdInput"> min
                  </div>
<?            }
              else {
?>                <div class="wdBoxContainer">
                    <select id="wdDescrip">
                      <option>WATER AND DRAG</option>
                      <option>COURSE CHANGE &amp; WALK</option>
                      <option>OTHER</option>
                    </select>

                    <input type="checkbox" class="wdBox"/>
                    <input type="text" value="20" maxlength="2" class="wdInput"> min
                  </div>
<?            }

              if ($d->get_info('ghost riders')) {
?>                <div class="ghostRidersContainer">
                    Ghost Riders
                    <input type="checkbox" checked class="ghostBox">
                    <input type="text" maxlength="2" class="ghostRiderInput" value="<?= $d->get_info('ghost riders') ?>">
                  </div>
<?            }
              else {
?>                <div class="ghostRidersContainer">
                    Ghost Riders
                    <input type="checkbox" class="ghostBox">
                    <input type="text" maxlength="2" class="ghostRiderInput">
                  </div>
<?            }
?>          </div>
            </li>

<?          if ($d->get_info('water and drag')) {
?>              <li class="waterAndDragRow" style="display:block;">
                  <span class="wdStartTime">08:33am</span> -
                  <span class="wdEndTime">08:34am</span>
                  <input type="text" class="wdDescription" value="<?= $d->get_info('water and drag description') ?>">
                </li>
<?          }
        }
    }

回答by mdvageek

In regards to PHP classes to generate HTML, you could use http://api20.cakephp.org/class/html-helperan object from the cake PHP framework. The others have already addressed your not so clean code.

关于生成 HTML 的 PHP 类,您可以使用http://api20.cakephp.org/class/html-helper一个来自 cake PHP 框架的对象。其他人已经解决了你不太干净的代码。

It uses this format: div( $class = NULL, $text = NULL, $options = array ( ) )

它使用这种格式: div( $class = NULL, $text = NULL, $options = array ( ) )

回答by pleasedontbelong

why not create your own clases?? or at least some functions... and i saw that you use alot of IF, you may clean it using vairables like when you have

为什么不创建自己的类?或者至少是一些功能......我看到你使用了很多 IF,你可以使用变量来清理它,就像你有

if($d->get_info('ghost riders')){
            echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" checked class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput" value="' . $d->get_info('ghost riders') .  '"></div>' . "\n";
        }else{
            echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput"></div>' . "\n";
        }

you could write:

你可以写:

$check = ($d->get_info('ghost riders'))?"checked":"";
echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" '.$check.' class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput" value="' . $d->get_info('ghost riders') .  '"></div>' . "\n";

it will look cleaner :) I've created a Form class that helps me when i have to create forms and the code is more legible

它看起来更干净:) 我创建了一个 Form 类,当我必须创建表单并且代码更清晰时,它可以帮助我

回答by John Stamoutsos

Something like this?

像这样的东西?

<?php

    $html->tag('doctype')->alone('html')->tag();
    $html->tag('html')->lang('en');

        $html->tag('head');
            $html->tag('meta')->charset('utf-8')->tag();
            $html->tag('meta')->httpequiv('X-UA-Compatible')->content('IE=edge')->tag();
            $html->tag('meta')->name('viewport')->content('width=device-width, initial-scale=1')->tag();
            $html->tag('meta')->name('description')->content('Brosta Tools')->tag();
            $html->tag('meta')->name('author')->content('Brosta')->tag();
            $html->tag('title')->text('Brosta Tools')->tag();
            $html->tag('link')->href('assets/plugins/bootstrap/css/bootstrap.min.css')->rel('stylesheet')->tag();
            $html->tag('link')->href('assets/plugins/bootstrap/css/simple-sidebar.css')->rel('stylesheet')->tag();
            $html->tag('link')->href('assets/plugins/prism/css/prism.css')->rel('stylesheet')->tag();
            $html->tag('link')->href('assets/plugins/normalize/css/normalize.css')->rel('stylesheet')->tag();
            $html->tag('link')->href('assets/plugins/brosta/css/brosta.css')->rel('stylesheet')->tag();

            $html->tag('script')->src('assets/plugins/bootstrap/js/jquery.js')->type('text/javascript')->tag();
            $html->tag('script')->src('assets/plugins/bootstrap/js/bootstrap.min.js')->type('text/javascript')->tag();
            $html->tag('script')->src('assets/plugins/prism/js/prism.js')->type('text/javascript')->tag();
            $html->tag('script')->type('text/javascript')->text('$("#menu-toggle").click(function(e) {e.preventDefault(); $("#wrapper").toggleClass("toggled"); });')->tag();
            $html->tag('script')->type('text/javascript')->text('
                window.onload = function () { 
                    var x = document.getElementsByClassName("token");
                    var i;
                    for (i = 0; i < x.length; i++) {
                        var variable = x[i].getAttribute("class").replace("token ", "");
                        var text = x[i].innerText.trim().replace("$", "");
                        if(!/[^a-zA-Z0-9]/.test(text) || text.indexOf("_") >= 0) {
                            x[i].className +=" " + variable + "-" + text;
                        }
                    }
                }
            ')->tag();
        $html->tag();

        $html->tag('body')->class('brosta');

            $html->include('snippets.brosta.navbar');

            $html->tag('div')->class('container-fluid brosta');
                $html->tag('div')->id('wrapper');
                    $html->tag('div')->id('sidebar-wrapper');
                        $html->tag('ul')->class('sidebar-nav');

                            $data = [
                                ['link' => '/Instalation', 'text' => 'Instalation'],
                                ['link' => '/Html', 'text' => 'Html']
                            ];

                            foreach($data as $link)
                            {
                                $html->tag('li');
                                    $html->tag('a')->href($link['link'])->text($link['text'])->tag();
                                $html->tag();
                            }

                        $html->tag();
                    $html->tag();
                    $html->tag('div')->id('page-content-wrapper');
                        $html->tag('div')->class('row');
                            $html->tag('div')->class('col-lg-12');
                                $html->tag('div')->class('panel panel-default');
                                    $html->tag('div')->class('panel-heading clearfix')->text('Without Time')->tag();
                                    $html->tag('div')->class('panel-body');
                                        $html->tag('p')->text('Make a file in your root public server. Ex: <code class="language-php">C:\xampp\htdocs\index.php</code>')->tag();
                                        $html->tag('pre')->class('language-php');
                                            $html->tag('code')->class('language-php')->text($html->specialChars('views/content.php'))->tag();
                                        $html->tag();
                                    $html->tag();
                                $html->tag();
                            $html->tag();
                        $html->tag();
                    $html->tag();
                $html->tag();
            $html->tag();
        $html->tag();
    $html->tag();

echo $html->get();

回答by ricotheque

This is a bit late, but I've recently written an object-oriented HTML generator for PHP. It supports nesting.

这有点晚了,但我最近为 PHP编写了一个面向对象的 HTML 生成器。它支持嵌套。

As an example, this...

举个例子,这...

$h = new \HTML;
echo $h::div(
    'class', 'my-class', 
    'id', 'my-id',
    $h::p(
        'class', 'paragraph',
        'It was a dark and stormy night, at least according to the beginning of the book.'
    )
);

...will create this markup (without spaces between the tags)...

...将创建此标记(标签之间没有空格)...

<div class="my-class" id="my-id">
    <p class="paragraph">It was a dark and stormy night, at least according to the book.</p>
</div>

Hope you find it useful!

希望你觉得它有用!

回答by Anibal Sanchez

studiowbe/htmlis the right package for me. It has a sound API, with chaining, and it is enabled on Composer.

studiowbe/html是适合我的包。它有一个健全的 API,带有链接,并且在 Composer 上启用。

$link = new Studiow\HTML\Element("a");
$link->setInnerHTML("Documents")
        ->setAttribute("href", "/documents")
        ->addClass("button")
        ->addClass("button-documents")
        ->setAttribute('title', "Go to documents");
echo (string) $link; // Outputs <a href="/documents" class="button button-documents" title="Go to documents">Documents</a>