使用面向对象样式为Smarty指定默认值

2022-04-07 00:00:00 php smarty

我只是非常缓慢地开始沉浸在面向对象编程中,所以请对我温柔点。

我有一个部分借用的Smarty定制类。这就是唯一的示例如何反映在我当前的项目中使用它的基本思想:

class Template {

    function Template() {
        global $Smarty;
        if (!isset($Smarty)) {
            $Smarty = new Smarty;
        }
    }

    public static function display($filename) {
        global $Smarty;
        if (!isset($Smarty)) {
            Template::create();
        }
        $Smarty->display($filename);
    }

然后在PHP中,我使用以下内容来显示基于上述示例的模板:

Template::display('head.tpl');
Template::display('category.tpl');
Template::display('footer.tpl');

我让下面的代码示例(见下文)通用地工作,所以我不会在每个PHP文件中一直重复上面的行(见前面的3行)。

我只想设置,例如:

Template::defauls();

这将加载:

Template::display('head.tpl');
Template::display('template_name_that_would_correspond_with_php_file_name.tpl');
Template::display('footer.tpl');

如您所见,Template::display('category.tpl');将始终根据PHP文件进行更改,其名称与模板名称对应,这意味着,例如,如果将PHP文件命名为stackoverflow.php,则其模板将为stackoverflow.tpl


我已经尝试了我的解决方案,效果很好,但我不喜欢它的外观(它的结构)。

我所做的是:

  1. 在配置中分配了一个变量并将其命名为$current_page_name(派生出当前的PHP页面名称,如下所示:basename($_SERVER['PHP_SELF'], ".php");),返回例如:category
  2. 在PHP文件中我使用Template::defaults($current_page_name);
  3. 在我的自定义Smarty类中,我添加了以下内容:


public static function defaults($template) {

   global $Smarty;

   global $msg;
   global $note;
   global $attention;
   global $err;

   if (!isset($Smarty)) {
      Templates::create();
   }
      Templates::assign('msg', $msg);
      Templates::assign('note', $note);
      Templates::assign('attention', $attention);
      Templates::assign('err', $err);

      Templates::display('head.tpl');
      Templates::display($template . '.tpl');
      Templates::display('footer.tpl');
}

有没有办法让它更简洁、更有条理?我知道代码审查,但我想让你们好好看看它。


解决方案

看起来您尚未加载Smarty,这就是发生错误的原因。你需要在课程开始前把Smarty包括进来。如果您关注我的另一个config suggestion,您也应该从包含那个开始。

在您的模板类中,只需添加以下函数:

function defaults() {
    // Don't know if you need the assignes, havn't used Smarty, but if so, insert them here...

    Template::display( Config::get('header_template') ); //header_template set in the Config file
    Template::display( basename($_SERVER['PHP_SELF'], ".php") . '.tpl' );
    Template::display( Config::get('footer_template') ); //footer_template set in the Config file
}

现在您应该可以在任何文件中使用它:

$template = new Template();
$template->defaults();

编辑:

单例在任何意义上都与全局相同,这将使您的问题保持不变。 但您的问题是,如果您尝试使用模板的静态函数之一,则处于"静态"模式,这意味着构造函数尚未运行。而Smarty还没有被分配到。如果你想走这条路,你可以做两个想法中的一个:

  1. 使模板成为真正的单例,意味着将构造函数设置为private添加一个函数getInstance,该函数返回类的一个实例,然后使用该对象调用其中的函数(不应是静态的),或

  2. 让所有这些静态函数检查是否设置了Smarty,如果未设置,则创建一个新的Smarty实例,否则使用已实例化的实例来运行其函数。

编辑2:

下面是制作单例的正确方法:

class Singleton {
    private static $instance = null;
    // private static $smarty = null;

    private function __construct() {
        //self::$smarty = new Smarty();
    }

    public static function getInstance() {
        if( self::$instance === null ) {
            self::$instance = self();
        }
        return self::$instance;
    }

    public function doSomething() {
        //self::$smarty->doSomething();
    }
}

使用方法如下:

$singleton = Singletong::getInstance();
$singleton->doSomething();

我注释掉了您可能想要做的事情,以使其成为Singleton Smarty对象的Singleton包装器。希望这能有所帮助。

编辑3:

这是您的代码的工作副本:

class Template {
    private static $smarty_instance;
    private static $template_instance;

    private function Template() {
        self::$smarty_instance = new Smarty();
        $this->create();
    }

    public static function getInstance() {
        if( ! isset( self::$template_instance ) ) {
            self::$template_instance = new self();
        }
        return self::$template_instance;
    }

    private function create() {
        self::$smarty_instance->compile_check = true;
        self::$smarty_instance->debugging = false;
        self::$smarty_instance->compile_dir   = "/home/docs/public_html/domain.org/tmp/tpls";
        self::$smarty_instance->template_dir  = "/home/docs/public_html/domain.org";
        return true;
    }

    public function setType($type) {
        self::$smarty_instance->type = $type;
    }

    public function assign($var, $value) {
        self::$smarty_instance->assign($var, $value);
    }

    public function display($filename) {
        self::$smarty_instance->display($filename);
    }

    public function fetch($filename) {
        return self::$smarty_instance->fetch($filename);
    }

    public function defaults($filename) {
        global $user_message;
        global $user_notification;
        global $user_attention;
        global $user_error;

        self::$smarty_instance->assign('user_message', $user_message);
        self::$smarty_instance->assign('user_notification', $user_notification);
        self::$smarty_instance->assign('user_attention', $user_attention);
        self::$smarty_instance->assign('user_error', $user_error);

        self::$smarty_instance->assign('current_page', $filename);

        self::$smarty_instance->display('head.tpl');
        self::$smarty_instance->display($filename . '.tpl');
        self::$smarty_instance->display('footer.tpl');
    }
}

使用此函数时,应按如下方式使用:

$template = Template::getInstance();
$template->defaults($filename);

立即尝试。

相关文章