Domanda

I'm rewriting a lot of my old mucky spaghetti code and am currently trying to get to grips with classes, functions and loosely rebuilding my site around MVC model.

However, I cannot get my header template include, to reference user account details which are autoloaded by my main config file and I think I'm missing out a very important step.

The error message is Fatal error: call to member function is_loggedin() on a non-object..., so I'm guessing that the include performed in template.class.php cannot access the account.class.php functions.

UPDATE: peforming a var_dump(get_included_files()) within header.tpl.php shows that both account.class.php and template.class.php are included (in that order). I also tried manually including account.class.php at the top of header.tpl.php to see if it would make any difference...it didnt. HELP :(

I should also note that I can call $_account->is_loggedin() from index.php with no issues. Jst not from within the included file header.inc.php.

Chances are I'm going abut this all wrong, so below is a simplified write-up of my code if anyone can offer some pointers:

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; ?>
È stato utile?

Soluzione

The $_account that you are trying to access is a variable in the function scope of your template::load method, the $_account that you initialized is a global variable.

If you want to use a global variable you should either declare it with global $_account within the function or use $GLOBALS['_account'].

A simple template example (the rest is copied from your source):

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>

It should also be noted that this is missing the C from MVC. It is only an example of how to make templates as classes.

Usually the index (or in this case default.php) only needs to decide which controller is suppose to handle the request. The controller then has to decide (or default to) which template should be used (if any).

Also it is better if all the html is contained in the templates, no output should be printed before the controller handles the request.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top