1

私はオブジェクト指向プログラミングに非常にゆっくりと没頭し始めているので、私に優しくしてください。

部分的に借用した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クラスで、次を追加しました。


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

それをより簡潔でよく構造化する方法はありますか?コードレビューについては知っていますが、皆さん、よく見ていただきたいと思います。

4

4 に答える 4

2

これは、Smartyをロードしていないように見えるため、エラーが発生します。クラスを開始する前に、Smartyを含めることから始める必要があります。私の他の構成の提案に従う場合は、それも含めることから始める必要があります。

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();

編集:

シングルトンはあらゆる意味でグローバルと同じであり、同じ問題を維持します。ただし、問題は、テンプレートの静的関数の1つを使用しようとすると、「静的」モードになっていることです。これは、コンストラクターが実行されていないことを意味します。そして、Smartyは割り当てられていません。この道に行きたい場合は、次の2つの考えのいずれかを実行できます。

  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();

これをシングルトン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);

やってみよう。

于 2012-09-16T15:13:58.160 に答える
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コードを作成することを学び、実践することでした。

于 2012-09-17T07:44:19.450 に答える
0

関数で現在のファイル名を取得できますdefaults()。次のコードを使用します。

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

$viewName必要な名前です。

于 2012-09-15T09:50:51.097 に答える
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

私はこれをちょっと速くしましたが、あなたが賢く使うことができる基本的な方法をあなたに示すためだけに。より完全なバージョンでは、コンパイルディレクトリが書き込み可能かどうか、またはファイルテンプレートが存在するかどうかなどを確認することをお勧めします。

于 2012-09-17T00:05:38.990 に答える