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

时间:2012-09-15 09:34:26

标签: 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. 在config中分配一个var并将其命名为$current_page_name(它派生当前的PHP页面名称,如:basename($_SERVER['PHP_SELF'], ".php");),返回,例如:category
  2. 在PHP文件中,我使用了Template::defaults($current_page_name);
  3. 在我的自定义Smarty课程中,我添加了以下内容:

  4. 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');
    }
    

    有没有办法让它更简洁,结构更好?我知道 Code Review ,但我希望你们好好看看它。

4 个答案:

答案 0 :(得分:2)

这看起来你没有加载Smarty,这就是错误发生的原因。你需要在课程开始之前先包括Smarty。如果您关注我的其他config suggestion,您应该首先包括那个。

在Template类中,只需添加以下函数:

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实例,否则使用已经实例化的实例来运行其功能。

  3. 编辑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();
    

    我评论了你可能想做的事情,使它成为围绕单身Smarty对象的单例包装器。希望这会有所帮助。

    编辑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);
    

    立即尝试。

答案 1 :(得分:0)

您可以在defaults()功能中获取当前文件名。使用这段代码:

$currentFile = $_SERVER['REQUEST_URI'];
$parts = explode('/', $currentFile);
$fileName = array_pop($parts);
$viewName = str_replace('.php', '.tpl', $fileName);

$viewName是您需要的名称。

答案 2 :(得分:0)

这是我为Smarty制作的快速包装器,希望它能为您提供一些想法

class Template extends Smarty
{
     public $template = null;
     public $cache    = null;
     public $compile  = null;

     public function var($name, $value, $cache)
     {
         $this->assign($name, $value, $cache);
     }

     public function render($file, $extends = false)
     {
         $this->prep();

         $pre  = null;
         $post = null;

         if ($extends)
         {
             $pre = 'extends:';
             $post = '|header.tpl|footer.tpl';
         }

         if ($this->prep())
         {
             return $this->display($pre . $file . $post);
         }
      }

      public function prep()
      {
          if (!is_null($this->template))
          {
              $this->setTemplateDir($this->template);

              return true;
          }

          if (!is_null($this->cache))
          {
              $this->setCacheDir($this->cache);
          }

          if (!is_null($this->compile))
          {
              $this->setCompileDir($this->compile);

              return true;
          }

              return false;
      }
}

Then you can use it like this

$view = new Template();

$view->template = 'path/to/template/';
$view->compile  = 'path/to/compile/'
$view->cache    = 'path/to/cache';

$view->assign('hello', 'world');

// or

$view->var('hello', 'world');

$view->render('index.tpl');

//or

$view->render('index.tpl', true); // for extends functionality

我做得这么快,但只是为了向您展示您可以使用聪明的基本方法。在更完整的版本中,您可能想要检查编译目录是否可写,或者是否存在文件模板等。

答案 3 :(得分:0)

经过几天的努力解决这个简单的问题后,我终于找到了工作且完全满意的解决方案。请记住,我只是面向对象编程的新手,这就是为什么花了这么长时间的主要原因。

我的主要想法是不要在我的初始代码中使用global $Smarty。我喜欢使用我的Smarty就像输入一样简单,例如:Template::assign('array', $array)。为了显示默认值,我提出了一个简单的解决方案(阅读我的初始帖子),现在可以使用Template::defaults(p());来显示或分配在项目的每个页面上重复的任何内容。

为此,我个人停止了以下完全可行的解决方案:

function p() {
    return basename($_SERVER['PHP_SELF'], ".php");
}

require('/smarty/Smarty.class.php');

class Template
{
    private static $smarty;
    static function Smarty()
    {
        if (!isset(self::$smarty)) {
            self::$smarty                 = new Smarty();
            self::Smarty()->compile_check = true;
            self::Smarty()->debugging     = false;
            self::Smarty()->plugins_dir   = array(
                '/home/docs/public_html/domain.com/smarty/plugins',
                '/home/docs/public_html/domain.com/extensions/smarty');
            self::Smarty()->compile_dir   = "/home/docs/public_html/domain.com/cache";
            self::Smarty()->template_dir  = "/home/docs/public_html/domain.org";
        }
        return self::$smarty;
    }
    public static function setType($type)
    {
        self::Smarty()->type = $type;
    }
    public static function assign($var, $value)
    {
        self::Smarty()->assign($var, $value);
    }
    public static function display($filename)
    {
        self::Smarty()->display($filename);
    }
    public static function fetch($filename)
    {
        self::Smarty()->fetch($filename);
    }
    public static function defaults($filename)
    {
        Template::assign('current_page_name', $filename);
        Template::display('head.tpl');
        Template::display($filename . '.tpl');
        Template::display('footer.tpl');
    }
}

如果您喜欢在项目中使用它,请在此帖子下留言,如果您认为我可以改进它或您有任何建议。

完成所有这些工作的最初想法是学习和练习以面向对象的方式编写PHP代码。