关于 php:如何从内容中获取页面 包含到前端控制器中

How to get page <title> from content include into front controller

我正在使用基于 PHP 的前端控制器模式,这样 index.php 提供页面结构和模板,每个页面的所有内容都包含在 /pages/ 中的包含文件中。

1
2
3
4
index.php
/pages/home.inc
/pages/about.inc
/pages/contact.inc

包含页面大多是简单的 HTML,因此客户端可以编辑页面而无需进行任何过于复杂的操作。

这种布局的问题在于,因为所有页面信息都在页面包含中,所以无法填充 <title> 元素。我可以在每个包含中放置一个 $title 变量,但它在头部之后加载,这为时已晚:

1
2
3
4
5
6
7
8
<html>
  <head>
    <?php echo $title; ?>     #$title is not set yet!
 </head>
  <body>
    <?php include($content); ?>              #now $title is set
 </body>
</html>

重要的是,内容文件是自包含的并且主要是 HTML,但也具有 PHP 代码的能力,正如我所提到的,因为客户将修改这些文件并增加太多的复杂性是一个问题。因此,例如,建立一个单独的页面标题数据库是行不通的,因为客户在创建新页面时不会更新数据库。

编辑:典型的页面包含可能如下所示。

1
2
3
4
5
6
7
8
9
10
Welcome
<p>blah</p>
<?php include("nav.php"); ?>
<p>more blah</p>
<p><center>[wp_ad_camp_2]</center></p><p>more blah</p>
<p>more blah</p>
<?php
  $pageJavascript ="alert('js!');";
  $pageTitle ="Cyberdyne Welcome Page";
?>


如果假设标题总是在第一行:
"我的页面标题";

1
2
3
$filename = '/pages/home.inc';
$fileLines = file($filename, FILE_SKIP_EMPTY_LINES);
$title = yourFunctionThatStripsKomma($fileLines[0]);

唯一不好的是,你必须确保第一行有标题。


选项:

1:使用输出缓冲

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
ob_start();
include($content);
$body = ob_get_contents();
ob_end_clean();
?>
<html>
 <head>
  <?php echo $title; ?>
 </head>
 <body>
 <?php echo $body; ?>
 </body>
</html>

优点:

  • 浏览器获得完全呈现的页面
  • 对 SEO 更友好(比 javascript 标题更新)
  • 无需 JS

缺点:

  • 需要缓冲内存中的所有页面

2:设置某种通用标题,稍后用javascript更新。

1
2
3
4
<script type="text/javascript">
with(document) {
  window.title = <?php echo json_encode($title); ?>;
}

优点:

  • 您保持与您现在使用的相同的流量。

缺点:

  • 对 SEO 不友好
  • 需要使用javascript