php动态HTML单元格意外生成
我目前正在开发接口部分a框架,以生成HTML标记。我面临的问题是为嵌套表和单元格生成标记时。 为此,我有一个html类,它定义了标签的常见期望。另一个类是htmlTable,它继承自hrml类,并为table、TR、TD定制。虽然我想在特定单元格上添加嵌套表,但结果却出乎意料。它生成数百个TDs和TR 下面的代码是定制发布在这里的,因为放置所有的代码会导致冗长和混乱。 还有一件事,我只专注于解决逻辑错误,以获得HTML标记的确切父元素、子元素和嵌套元素 我已经尽了最大努力,但没能把这个修好。这对你们中的一些人来说可能很容易。所以请告诉我你的解决方案。我得去上班了,所以我一回来就会回复。 谢谢php动态HTML单元格意外生成,php,html,oop,Php,Html,Oop,我目前正在开发接口部分a框架,以生成HTML标记。我面临的问题是为嵌套表和单元格生成标记时。 为此,我有一个html类,它定义了标签的常见期望。另一个类是htmlTable,它继承自hrml类,并为table、TR、TD定制。虽然我想在特定单元格上添加嵌套表,但结果却出乎意料。它生成数百个TDs和TR 下面的代码是定制发布在这里的,因为放置所有的代码会导致冗长和混乱。 还有一件事,我只专注于解决逻辑错误,以获得HTML标记的确切父元素、子元素和嵌套元素 我已经尽了最大努力,但没能把这个修好。这对
<?php
// scHTML.php
class HTML
{
protected $tag;
protected $id;
protected $values;
protected $childList;
protected $body;
public function __construct($tag,$id)
{
$this->tag=$tag;
$value= array('id'=>$id);
$this->setValues($value);
}
// to add nested tag
public function addChildTag(HTML $child)
{
$this->childList[]=$child;
}
// to add key and value on opening tag
public function setValues($values)
{
if(count($values)>0)
{
foreach($values as $key=>$value)
{
$this->values[$key]=$values;
}
}
}
// value inside tag
public function setBody($body)
{
$this->body=$body;
}
// generate HTML code
public function getHTML()
{
$return= '<'.$this->tag;
if(count($this->values)>0)
{
foreach($this->values as $key=>$value)
{
$return.=' '.$key.'= "'.$value.'" ';
}
}
$return.= '>
';
if(count($this->childList)>0)
{
$return.=
$this->body
;
foreach($this->childList as $child)
{
$return.=
$child->getHTML();
}
}
$return.=' </'.$this->tag.'>';
return $return;
}
public function __toString()
{
return $this->getHTML();
}
}
?>
下面是表的继承类
<?php
//scHTMLTable.php
include_once("scHTML.php");
class HTMLTable extends HTML
{
protected $cells; // logical grid of cells for current table
protected $row;
protected $column;
public function __construct($row,$column,$id)
{
$this->row=$row;
$this->column=$column;
$this->initiateTable();
$values['border']='1px';
$this->setValues($values);
parent::__construct("table",$id);
}
// initaite table cells according to row and column provided
private function initiateTable()
{
$td=new HTML("td",NULL);
$td->setBody(' ');
for($i=1;$i<=$this->row;$i++)
{
for($j=1;$j<=$this->column;$j++)
{
$this->addCell($i,$j,$td);
}
}
}
// set child element as body on a cell
public function addChildOnCell($row,$column,HTML $child)
{
$td=$this->cells[$row][$column];
$td->addChildTag($child);
$this->addCell($row,$column,$child);
}
// set cell
public function addCell($row,$column,HTML $cell)
{
$this->cells[$row][$column]=$cell;
}
// set TR as child and call parent method to generate html code.
public function getHTML()
{
for($i=1;$i<=$this->row;$i++)
{
$tr=new HTML("tr",NULL);
for($j=1;$j<=$this->column;$j++)
{
$td=$this->cells[$i][$j];
$tr->addChildTag($td);
}
$this->addChildTag($tr);
}
return parent::getHTML();
}
public function __toString()
{
return $this->getHTML();
}
}
?>
这里是实现
<?php
include_once("scHTML.php");
include_once("scHTMLTable.php");
$html= new HTML("html",NULL);
$body=new HTML("body",NULL);
// three table to be tested
$a= new HTMLTable(3,3,"grandparent");
$b=new HTMLTable(3,3,"parent");
$c=new HTMLTable(1,1,"child");
$b->addChildOnCell(2,2,$c);
$a->addChildOnCell(2,2,$b);
$body->addChildTag($a);
$html->addChildTag($body);
echo $html;
?>
我正在寻找的输出源代码就在这附近
<html>
<body>
<table border="1">
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td><table border="1">
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td><table border="1">
<tr>
<td> </td>
</tr>
</table></td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
</table></td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
</table>
</body>
</html>
现在是2015年,你不应该手动包含文件;有明确的编码标准,所以您应该有名称空间,并在主应用程序中注册自动加载程序 此外,只要您打算以这种方式进行字符串构建,在表示表的对象上使用_-toString()方法,您就应该为嵌套部分提供其他类,每个类都有自己的_-toString方法;所以您可以拥有HtmleElement类(您已经拥有)、table(您已经拥有,但它并不理想)、table行、table单元格 扩展它,如果您采取这条路线,您应该扩展所有HtmleElement,并为您想要以鹦鹉学舌的方式完成事情的时候提供一个rawString HtmleElement扩展类
- 表row uu-toString方法只需迭代包含的单元格并返回它们的u-toString方法
- 表将对行进行迭代,并调用它们的_toString方法
- table cell(最难/最不难的部分)将获取实现HtmleElement的实例,并通过调用其_toString方法对其进行迭代
如果表变得太大,您会希望您刚刚编写了一系列视图,这些视图使用一个级别的XYdata,或者以另一种方式简化;但是这种嵌套视图的数据结构,除非您正在使用JSON或XML(对于XML,只需使用XSL);从SQL Server、MySQL、search On中检索,或者真的用…做那么多有用的事情,都不是件好事。我同意mrmeses的观点,我认为您的表类做得太多了,每个节点类型只负责生成自己的DOM表示。但是,任何到字符串/到html的递归应该只在DOM中向下移动(不需要调用父级以获得渲染帮助)。下面是一个使用一些自定义API方法名称的快速演示:
class HTML
{
private $tagName;
protected $attributes = [];
protected $children = [];
private $text = '';
public function __construct($tagName, $text='') {
$this->tagName = strtolower($tagName);
$this->text = $text;
}
public function addChildTag(HTML $n) {
$this->children[] = $n;
return $this;
}
public function getHTML($depth=0) {
$padding = str_repeat("\t", $depth);
$result = "$padding<$this->tagName";
foreach($this->attributes as $k => $v) {
$result .= " $k=\"".htmlspecialchars($v)."\"";
}
if (count($this->children) == 0 && strlen($this->text) == 0) {
$result .= " />\n";
}
else {
$result .= ">";
$result .= $this->text;
if (count($this->children) > 0) $result .= "\n";
foreach($this->children as $c) {
$result .= $c->getHTML($depth+1);
}
$result .= "$padding</$this->tagName>\n";
}
return $result;
}
public function tagName() { return $this->tagName; }
public function findChild($tagName, $index=0) {
$nodes = array_filter($this->children, function($e) use ($tagName) { return $e->tagName() == $tagName; });
return count($nodes) ? $nodes[$index] : null;
}
public function __toString() { return $this->getHTML(); }
}
class HTMLTable extends HTML {
public function __construct($rows, $cols, $id) {
parent::__construct("table");
$this->attributes['id'] = $id;
$this->attributes['border'] = '1px';
for($r=0; $r<$rows; $r++) {
$row = new HTML("tr");
for($c=0; $c<$cols; $c++) {
$cell = new HTML("td");
$row->addChildTag($cell);
}
$this->addChildTag($row);
}
}
public function addChildOnCell($row, $col, HTML $child) {
return $this->findChild("tr", $row-1)->findChild("td", $col-1)->addChildTag($child);
}
}
$html= new HTML("html");
$body=new HTML("body");
// three table to be tested
$a= new HTMLTable(3,3,"grandparent");
$b=new HTMLTable(3,3,"parent");
$c=new HTMLTable(1,1,"child");
$b->addChildOnCell(2,2,$c);
$a->addChildOnCell(2,2,$b);
$body->addChildTag($a);
$html->addChildTag($body);
echo $html;
类HTML
{
私有$标记名;
受保护的$attributes=[];
受保护的$children=[];
私人$text='';
公共函数构造($tagName,$text=''){
$this->tagName=strtolower($tagName);
$this->text=$text;
}
公共函数addChildTag(HTML$n){
$this->children[]=$n;
退还$this;
}
公共函数getHTML($depth=0){
$padding=str_repeat(“\t”,$depth);
$result=“$paddingtagName”;
foreach($此->属性为$k=>$v){
$result.=“$k=\”.htmlspecialchars($v)。“\”;
}
如果(计数($this->children)==0&&strlen($this->text)==0){
$result.=“/>\n”;
}
否则{
$result.=“>”;
$result.=$this->text;
如果(计数($this->children)>0)$result.=“\n”;
foreach($this->children as$c){
$result.=$c->getHTML($depth+1);
}
$result.=“$paddingtagName>\n”;
}
返回$result;
}
公共函数标记名(){return$this->tagName;}
公共函数findChild($tagName,$index=0){
$nodes=array_filter($this->children,function($e)use($tagName){return$e->tagName()=$tagName;});
返回计数($nodes)$nodes[$index]:null;
}
公共函数_toString(){return$this->getHTML();}
}
类HTMLTable扩展了HTML{
公共函数构造($rows、$cols、$id){
父项::_构造(“表”);
$this->attributes['id']=$id;
$this->attributes['border']='1px';
对于($r=0;$raddChildTag($row));
}
}
公共函数addChildOnCell($row,$col,HTML$child){
返回$this->findChild($tr',$row-1)->findChild($td',$col-1)->addChildTag($child);
}
}
$html=新html(“html”);
$body=新HTML(“body”);
//需要测试的三个表
$a=新HTMLTable(3,3,“祖父母”);
$b=新HTMLTable(3,3,“父项”);
$c=新HTMLTable(1,1,“子”);
$b->addChildOnCell(2,2,$c);
$a->addChildOnCell(2,2$b);
$body->addChildTag($a);
$html->addChildTag($body);
echo$html;
这将导致输出:
<html>
<body>
<table id="grandparent" border="1px">
<tr>
<td />
<td />
<td />
</tr>
<tr>
<td />
<td>
<table id="parent" border="1px">
<tr>
<td />
<td />
<td />
</tr>
<tr>
<td />
<td>
<table id="child" border="1px">
<tr>
<td />
</tr>
</table>
</td>
<td />
</tr>
<tr>
<td />
<td />
<td />
</tr>
</table>
</td>
<td />
</tr>
<tr>
<td />
<td />
<td />
</tr>
</table>
</body>
</html>