我只是慢慢开始陷入面向对象的编程,所以请温柔地对待我。
我有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
。
我已经尝试过我的解决方案,但是我不喜欢它的外观(它的结构方式)。
我做的是:
$current_page_name
(它派生当前的PHP页面名称,如:basename($_SERVER['PHP_SELF'], ".php");
),返回,例如:category
。Template::defaults($current_page_name);
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 ,但我希望你们好好看看它。
答案 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还没有被分配。如果你想走这条路,你可以做两个中的一个想法:
使模板成为一个真正的单例,意味着将构造函数设置为private
添加一个函数getInstance,它返回一个类的实例,然后使用该对象调用其中的函数(应该不是静止的,或
让所有这些静态函数检查是否设置了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);
立即尝试。
答案 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代码。