我有大约 100 篇文章的列表,每篇文章中都有一个条款列表。 这些条款是不同深度级别的列表。
$clauses = array(
[
'Fields' => ['Clause' => 'clause 1', 'Status' => 'Draft']
],
[
'Fields' => ['Clause' => 'clause 2', 'Status' => 'Draft'],
'SubClauses' => [
[
'Fields' => ['Clause' => 'clause 2_a', 'Status' => 'Draft'],
'SubClauses' => [
[
'Fields' => ['Clause' => 'clause 2_a_1', 'Status' => 'Draft']
],
[
'Fields' => ['Clause' => 'clause 2_a_2', 'Status' => 'Draft']
]
]
]
]
],
[
'Fields' => ['Clause' => 'clause 3', 'Status' => 'Draft']
]
);
echo PHP_EOL;
为了从 $clauses 数组创建一个 html 有序列表,我构建了这个:
function htmlList ( $clauses, $depth = 0 ) {
if ( $depth == 0 ) {
echo '<ol type="1">';
} elseif ( $depth == 1 ) {
echo '<ol type="i">';
} else {
echo '<ol type="a">';
}
foreach ( $clauses as $key => $clause ) {
if ( isset($clauses[$key]['SubClauses']) ) {
echo ' <li>' . $clauses[$key]['Fields']['Clause'];
htmlList ( $clauses[$key]['SubClauses'], ++$depth );
} elseif ( isset($clauses[$key]['Fields']) ) {
echo ' <li>' . $clauses[$key]['Fields']['Clause'] . '</li>';
}
}
$depth--;
echo ' </li>';
echo '</ol>';
}
htmlList ( $clauses );
echo PHP_EOL;
它仅构建单篇文章的列表。 当代码循环到下一篇文章时,我收到错误,因为函数已经定义了。
我想将html保留在模板中,而不是将其放在代码文件中,所以我在模板中有可以在那里写入html的功能。
我需要在下一篇文章循环时更改函数的名称,因此我将其转换为闭包并将其分配给变量。 我正在传递该函数,因为我需要它递归。
$htmlList = function ( $clauses, $depth = 0 ) use ( &$htmlList ) {
if ( $depth == 0 ) {
echo '<ol type="1">';
} elseif ( $depth == 1 ) {
echo '<ol type="i">';
} else {
echo '<ol type="a">';
}
foreach ( $clauses as $key => $clause ) {
if ( isset($clauses[$key]['SubClauses']) ) {
echo ' <li>' . $clauses[$key]['Fields']['Clause'];
$htmlList ( $clauses[$key]['SubClauses'], ++$depth );
} elseif ( isset($clauses[$key]['Fields']) ) {
echo ' <li>' . $clauses[$key]['Fields']['Clause'] . '</li>';
}
}
$depth--;
echo ' </li>';
echo '</ol>';
};
$htmlList ( $clauses );
echo PHP_EOL;
这也适用于单篇文章,但允许动态更改名称。 然后,我将保存函数名称的变量的名称设为动态。
$articles = array(
['Title' => 'title 1', 'Status' => 'Draft'],
['Title' => 'title 2', 'Status' => 'Draft'],
);
for ( $i = 0; $i < sizeof($articles); $i++ ) {
echo $articles[$i]['Title'] . PHP_EOL;
$htmlList = 'htmlList' . '_' . $i;
$$htmlList = function ( $clauses, $depth = 0 ) use ( &$$htmlList ) {
if ( $depth == 0 ) {
echo '<ol type="1">';
} elseif ( $depth == 1 ) {
echo '<ol type="i">';
} else {
echo '<ol type="a">';
}
foreach ( $clauses as $key => $clause ) {
if ( isset($clauses[$key]['SubClauses']) ) {
echo ' <li>' . $clauses[$key]['Fields']['Clause'];
$$htmlList ( $clauses[$key]['SubClauses'], ++$depth );
} elseif ( isset($clauses[$key]['Fields']) ) {
echo ' <li>' . $clauses[$key]['Fields']['Clause'] . '</li>';
}
}
$depth--;
echo ' </li>';
echo '</ol>';
};
$$htmlList ( $clauses );
}
这就是它破裂的地方。 它不喜欢 use() 中的可变命名函数名,并且在 $$ 处出错,因为它是一个可变变量,它只允许 1 $ 而我有 2 $$,因为变量名的值发生了变化。
是否最好将函数保存在模板外部的主代码中,这样就不必为每篇文章重新构建,或者将函数放在模板中并将 html 保留在主代码文件之外? 围绕 html 的所有其他构造通常都在模板文件中。
如何将循环的每篇文章的子句转换为 html 列表?
要解决您的问题并为每篇文章生成 HTML 列表而不会遇到函数重新定义错误,您可以在循环外部定义一次递归函数,然后为每篇文章调用它。这种方法将您的 HTML 保留在模板内,并避免多次重新定义函数。
$htmlList = function ($clauses, $depth = 0) use (&$htmlList) {
if ($depth == 0) {
echo '<ol type="1">';
} elseif ($depth == 1) {
echo '<ol type="i">';
} else {
echo '<ol type="a">';
}
foreach ($clauses as $clause) {
echo '<li>' . $clause['Fields']['Clause'];
if (isset($clause['SubClauses'])) {
$htmlList($clause['SubClauses'], $depth + 1);
}
echo '</li>';
}
echo '</ol>';
};
$clauses1 = array(
[
'Fields' => ['Clause' => 'clause 1', 'Status' => 'Draft']
],
[
'Fields' => ['Clause' => 'clause 2', 'Status' => 'Draft'],
'SubClauses' => [
[
'Fields' => ['Clause' => 'clause 2_a', 'Status' => 'Draft'],
'SubClauses' => [
[
'Fields' => ['Clause' => 'clause 2_a_1', 'Status' => 'Draft']
],
[
'Fields' => ['Clause' => 'clause 2_a_2', 'Status' => 'Draft']
]
]
]
]
],
[
'Fields' => ['Clause' => 'clause 3', 'Status' => 'Draft']
]
);
$clauses2 = array(
);
$articles = array(
[
'Title' => 'Article 1',
'Status' => 'Draft',
'Clauses' => $clauses1
],
[
'Title' => 'Article 2',
'Status' => 'Draft',
'Clauses' => $clauses2
],
);
foreach ($articles as $article) {
echo '<h2>' . $article['Title'] . '</h2>';
if (isset($article['Clauses'])) {
$htmlList($article['Clauses']);
}
}