我很难理解如何调用特定的foreach
命令将允许我调用以显示需求。
<?php
$html = array(
array(
'tag_name' => 'h1',
'content' => 'My page title'
),
array(
'tag_name' => 'p',
'attributes' => array(
'class' => 'big shiny'
),
'content' => 'Pizza is one of the main food groups. 5 out of 4 dentists recommend pizza over any other form of nutrition. Thou shalt eat thine pizza.'
),
array(
'tag_name' => 'label',
'attributes' => array(
'for' => 'like_pizza'
),
'content' => 'Do you like pizza?'
),
array(
'tag_name' => 'input',
'attributes' => array(
'type' => 'checkbox',
'id' => 'like_pizza',
'name' => 'like_pizza',
'checked' => 'checked'
)
)
);
?>
如何使用foreach
循环输出以下HTML。
<h1>My Page Title</h1>
<p class="big shiny">Pizza is one of the main food groups. 5 out of 4 dentists recommend pizza over any other form of nutrition. Thou shalt eat thine pizza.</p>
<label for="like_pizza">Do you like pizza?</label>
<input type="checkbox" id="like_pizza" name="like_pizza" checked="checked">
首先请回顾一下这个http://php.net/manual/de/control-structures.foreach.php(只是为了教育)。
方法(与所有树状结构一样,因此,标记语言如HTML、XML和背后的任何数据表示)是使用递归。
因此,您只需要考虑第一级标记本身的求值,然后捕获异常情况。
<?php
$html = array(
array(
'tag_name'=>'h1',
'content'=>'My page title'
),
array(
'tag_name'=>'p',
'attributes'=>array(
'class'=>'big shiny'
),
'content'=>'Pizza is one of the main food groups. 5 out of 4 dentists recommend pizza over any other form of nutrition. Thou shalt eat thine pizza.'
),
array(
'tag_name'=>'label',
'attributes'=>array(
'for'=>'like_pizza'
),
'content'=>'Do you like pizza?'
),
array(
'tag_name'=>'input',
'attributes'=>array(
'type'=>'checkbox',
'id'=>'like_pizza',
'name'=>'like_pizza',
'checked'=>'checked'
)
)
);
?>
纠正你的缩进,看看你的格式:当然,根是一个只包含数组的数组。这些数组中的每一个都包含键<->值对,这些值对构成了一个标记的信息。
因此,您必须编写一个函数来处理信息并将其转换为标记字符串表示。
function formatTag($tag, $attributes, $content)
{
$str = "<".$tag;
foreach($attributes as $attrName => $attrValue)
{
$val = $attrValue;
if(is_array($attrValue)) // Consider multiple class assignments!
foreach($attrValue as $value)
$val .= $value.' ';
$str .= ' '.$attrName.'="'.$val.'"';
}
$str .= ">".$content."</".$tag.">";
return $str;
}
function handleTagArray($arr) {
if(!array_key_exists("tag_name"))
throw new Exception("Invalid format!");
$tag = $arr["tag_name"];
$attributes = array_key_exists("attributes") ? $arr["attributes"] : "";
$content = array_key_exists("content") ? $arr["content"] : "";
if(is_array($content))
{
foreach($content as $child) // One tag could have multiple children!
{
if(is_array($child)) // Distinguish mixed children types tag or text here!
$content .= handleTagArray($child);
else
$content .= $child;
}
return formatTag($tag, $attributes, $content);
}
这个解决方案考虑到一个标签可以有多个子标签。
array ( 'tag_name'=> 'body',
'content' => array (
array ( 'tag_name' => 'h1',
'content' => 'My page title'
),
array ( 'tag_name' => 'p',
'attributes' // ...
)
);
该解决方案还考虑到<div id="test" class="testdiv noborder fullwidth">Test</div>
这样的标签,即一个标签有多个类的可能性。你必须在你的数组结构中相应地写:
//...
array( 'tag_name' => 'div',
'attributes' => array('id'=>'test', 'class'=>array('testdiv', 'noborder', 'fullwidth')),
'content' => 'Test' );
另外,考虑到默认情况下XML和HTML要求你有一个根节点,即第一个数组也应该包含标签信息,子数组应该包装在它的内容数组中。
编辑:根据@faino对array_key_exists的注释调整了我的代码。今天学了点新东西。D谢谢你!
编辑:添加了子类型标记<->文本的区别,参见代码!
像这样的东西会做到这一点,它有点粗糙,但这是一个很好的开始,你可以从中学习。查看array_key_exists和foreach文档以获得更好的理解和更多示例。
<?php
$html = array(
array(
'tag_name'=>'h1',
'content'=>'My page title'
),
array(
'tag_name'=>'p',
'attributes'=>array(
'class'=>'big shiny'
),
'content'=>'Pizza is one of the main food groups. 5 out of 4 dentists recommend pizza over any other form of nutrition. Thou shalt eat thine pizza.'
),
array(
'tag_name'=>'label',
'attributes'=>array(
'for'=>'like_pizza'
),
'content'=>'Do you like pizza?'
),
array(
'tag_name'=>'input',
'attributes'=>array(
'type'=>'checkbox',
'id'=>'like_pizza',
'name'=>'like_pizza',
'checked'=>'checked'
)
)
);
// ECHO this function where needed
function format_array($arr) {
$output = "";
foreach($arr as $inner) {
$output .= "<" . $inner["tag_name"];
if(array_key_exists("attributes", $inner)) {
foreach($inner["attributes"] as $name => $val) {
$output .= " " . $name . "='"" . $val . "'"";
}
}
$output .= ">";
if(array_key_exists("content", $inner)) {
$output .= $inner["content"] . "</" . $inner["tag_name"] . ">";
}
}
return($output);
}
// Display the HTML
echo(format_array($html));
?>
您只需调用该函数,并在您的HTML中返回该数组。
或者,您可以使用DOMDocument
类并使用其有用的方法。考虑这个例子:
$html = array( array( 'tag_name'=>'h1', 'content'=>'My page title' ), array( 'tag_name'=>'p', 'attributes'=>array( 'class'=>'big shiny' ), 'content'=>'Pizza is one of the main food groups. 5 out of 4 dentists recommend pizza over any other form of nutrition. Thou shalt eat thine pizza.' ), array( 'tag_name'=>'label', 'attributes'=>array( 'for'=>'like_pizza' ), 'content'=>'Do you like pizza?' ), array( 'tag_name'=>'input', 'attributes'=>array( 'type'=>'checkbox', 'id'=>'like_pizza', 'name'=>'like_pizza', 'checked'=>'checked' ) ));
$dom = new DOMDocument();
$dom->loadHTML('<html></html>');
foreach($html as $tags) {
$element = null;
// tag
if(isset($tags['tag_name'])) {
$content = isset($tags['content']) ? $tags['content'] : '';
$element = $dom->createElement($tags['tag_name'], $content);
}
// attributes
if(isset($tags['attributes'])) {
foreach($tags['attributes'] as $attribute_value => $value) {
$attribute = $dom->createAttribute($attribute_value);
$attribute->value = $value;
$element->appendChild($attribute);
}
}
$dom->appendChild($element);
}
echo $dom->saveHTML();
你可以使用递归函数
function display($data){
foreach($data as $inner)
{
$ret = "<".$inner['tag'];
if(is_array($inner['attributes']) //check if there are attributes
foreach($inner['attributes'] as $key => $value){
$ret .= ' '.$key.'="'.$value.'"';
}
$ret .= ">".$inner['content'];
if(is_array($inner['content'])) $ret .= display($inner['content']); //call the function recursive for the nested ones
$ret .= "</".$inner['tag'].">";
}
return $ret;
}
,像这样使用:
echo display($html);