了解变量的类和范围

时间:2013-09-09 10:56:56

标签: php class autoloader

我正在重写我的许多旧的意大利面条代码,目前正试图掌握类,功能以及围绕MVC模型松散重建我的网站。

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

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

更新:在header.tpl.php中执行var_dump(get_included_files())表示包含account.class.php和template.class.php(按此顺序)。我也尝试手动包括header.tpl.php顶部的account.class.php,看看它是否会有任何区别......它没有。帮助:(

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

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

的index.php

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

defaults.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
  }
}

template.class.php

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

header.tpl.php

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

1 个答案:

答案 0 :(得分:2)

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

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

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

<强> Template.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;
    }
}

<强> defaults.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();

<强>的index.php

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

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

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

如果模板中包含所有html,最好不要在控制器处理请求之前打印输出。