4

我正在尝试用 PHP 构建一个 CMS,但在构建模板系统时遇到了一些麻烦。我不想使用 Smarty 或 Twig,因为我不想依赖外部框架,直到我自己可以流利地编写代码。这一切都是为了提高我的学习能力(从我的角度来看)。

所以我一直在计划模板如何工作,但在错误检查方面遇到了麻烦。

这是它如何工作的基本概述。

(非常)简单的示例模板:

<html>
<p>{output $randomNumber}</p>{output $databaseDump}
<div>{output $databaseAndUsersPasswords}</div>
</html>

由我的解析器解析:

<html>
<p><?php echo $randomNumber?></p><?php echo $databaseDump?>
<div><?php echo $databaseAndUsersPasswords?></div>
</html>

然后我使用 eval 运行解析后的模板。

我的问题在于错误检查。如果设计人员出错了,则几乎没有针对错误的保护措施。启用错误抑制后,页面的一部分将丢失其内容。我希望它是全部或全部。我想不出一个简单的解决方案可以让我检查错误。

另外,您认为我可以使用正则表达式和 str_replace 来解析模板吗?我一直在阅读其他一些框架解决方案,但看起来都非常复杂,我找不到他们解析系统的核心。

请随意批评我的技术。我是来学习的。

4

2 回答 2

4

如果你想要全部或全部,你可以简单地配置一个错误处理程序并让它抛出异常:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    if (error_reporting()) {
        // the @ operator wasn't used, throw it.
        throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
    }
}
set_error_handler("exception_error_handler");

在此之后,您可以在块include()内生成脚本try { } catch并使用输出缓冲来防止任何不需要的输出:

try {
    ob_start(); // stop output

    include '/path/to/script';

    ob_end_flush(); // flush buffer and stop output buffering
} catch (ErrorException $e) {
    ob_end_clean(); // clear buffer and stop output buffering
}

也可以看看:ErrorException


关于编写自己的模板引擎,我使用以下规则:

如果它看起来像 PHP,请使用 PHP!

对于设计人员来说,几乎类似于 PHP 的语法与 PHP 本身一样难以学习,但是您为确保模板不会绊倒您自己的解析器而付出的努力绝对是切实可行的。

如果您想要更好地融入设计师的工作,请查看这个名为的项目,该项目PHPTAL使用 XHTML 属性进行变量替换并声明循环块、宏等。


有关错误报告和日志记录的更多信息:错误记录,以一种流畅的方式

于 2012-12-28T08:10:09.210 回答
1

首先,除非有必要并且您别无选择,否则不要使用eval(阅读注意事项)。另一件事是,对于模板系统来说,查看、转换为 php 然后包含(运行)它是多余的。

我会使用MVC 模式,让控制器加载视图并将必要的信息传递给它,而不将其作为脚本处理

样本:


基本控制器:

abstract class Controller {
    protected function Render($view, $data = array()) {
        $viewStr = file_get_contents(__PATH_TO_VIEW__.$view.'.html');

        $viewStr = preg_replace_callback('/\{(\w+)\}/',
                                        function ($matches) use ($data) {
                                            return isset($data[$matches[1]]) ?
                                                          $data[$matches[1]] : '';
                                        }, $viewStr);
        echo $viewStr;
    }
}

自定义控制器:

class MyController extends Controller {
    public function index() {
        $this->Render('myView', array('test' => 'some test string'));
    }
}

自定义视图(myView.html在本例中):

<b>{test}</b>

输出应该是:

一些测试字符串


如您所见,您正在使用字符串,您不运行任何东西,所以现在您可以完全控制视图并且设计器无法产生 php 错误。

PS随意调整这个充足的到你现有的代码。;)

于 2012-12-28T08:16:31.630 回答