3

我正在重写我的很多旧的肮脏的意大利面条代码,目前正试图掌握类、函数并围绕 MVC 模型松散地重建我的网站。

但是,我无法让我的标题模板包含,以引用由我的主配置文件自动加载的用户帐户详细信息,我认为我错过了一个非常重要的步骤。

错误消息是Fatal error: call to member function is_loggedin() on a non-object...,所以我猜测在 template.class.php 中执行的包含无法访问 account.class.php 函数。

更新:var_dump(get_included_files())在 header.tpl.php 中执行 a 表明 account.class.php 和 template.class.php 都包括在内(按此顺序)。我还尝试在 header.tpl.php 的顶部手动包含 account.class.php 以查看它是否会有所不同......它没有。帮助 :(

我还应该注意,我可以毫无问题$_account->is_loggedin()地从 index.php 调用。Jst 不在包含的文件 header.inc.php 中。

我可能会遇到这一切都错了,所以如果有人可以提供一些指示,下面是我的代码的简化编写:

索引.php

<php require 'defaults.php'; ?>
<html>
<head>
...
</head>
<body>
<?php $_template->load('header'); ?>
....
</body>

默认值.php

session_start();

// define path settings
// connect to database, memcache
// lots of other stuff....

//autoloader for functions
spl_autoload_register(function ($class) {
  if (file_exists(CLASS_PATH.DS.$class.'.class.php'))
  {
    include CLASS_PATH.DS.$class.'.class.php';
  }
});

$_account = new account();  // autoload user account stuff
$_template = new template(); // autoload templates

account.class.php

class account
{
  private $db;

  public function __construct($db) {
    $this->db = $db;
  }


  public function is_loggedin() {
    // do various session checks
  }
}

模板类.php

class template
{
  public function load($template)
  {
    if (file_exists(TPL_PATH.DS.$template.'.tpl.php'))
    {
      include TPL_PATH.DS.$template.'.tpl.php';
    }
  }
}

头文件.tpl.php

<div id="header">
<?php if($_account->is_loggedin() == true): ?>
  <p>logged in</p>
<?php else: ?>
  <p>not logged in</p>
<?php endif; ?>
4

1 回答 1

2

$_account您尝试访问的是方法函数范围内的变量,template::load$_account初始化的是全局变量。

如果你想使用一个全局变量,你应该global $_account在函数中声明它或者使用$GLOBALS['_account'].

一个简单的模板示例(其余部分从您的源代码中复制):

模板.class.php

interface IApiHandler {
    public function printContent();
}

SomeTemplate.class.php

class SomeTemplate implements Template {
    public function printContent() {
        $account = Account::getCurrent();
        ?>
        <div id="header">
        <?php if($account->is_loggedin() == true): ?>
            <p>logged in</p>
        <?php else: ?>
            <p>not logged in</p>
        <?php endif;
    }
}

Account.class.php

class Account {
    private static $current = null;
    public static function getCurrent() {
        if(self::$current === null) {
            self::$current = new Account();
        }
        return self::$current;
    }
    public function __construct() {
        //account init...
    }
    public function isLoggedIn() {
        return rand()%2;
    }
}

默认值.php

session_start();

// define path settings
// connect to database, memcache
// lots of other stuff....

//autoloader for functions
spl_autoload_register(function ($class) {
  if (file_exists(CLASS_PATH.DS.$class.'.class.php'))
  {
    include CLASS_PATH.DS.$class.'.class.php';
  }
});

$headerTemplate = new HeaderTemplate();//not included in the example...
$bodyTemplate = new SomeTemplate();

索引.php

<php require 'defaults.php'; ?>
<html>
<head>
...
</head>
<body>
<?php $headerTemplate->printContent(); ?>
<?php $bodyTemplate->printContent(); ?>
</body>

还应该注意的是,这缺少 MVC 中的 C。这只是如何将模板制作为类的示例。

通常索引(或者在这种情况下为 default.php)只需要决定哪个控制器应该处理请求。然后控制器必须决定(或默认)应该使用哪个模板(如果有的话)。

此外,如果所有 html 都包含在模板中会更好,在控制器处理请求之前不应打印任何输出。

于 2013-09-09T12:14:16.227 回答