通过PHP生成简单的HTML
我有一个HTML标记数组:通过PHP生成简单的HTML,php,html,Php,Html,我有一个HTML标记数组: class sampleHTML { public function __construct( $tag = [] ) { $html = [ [ 'type' => 'p', 'class' => '.sample-class', 'content' => 'Sample content'
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
oddiv
,那么您可以仅为那些具有不同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
}