So I been working on creating my own framework. Basically a starting point for developing sites that all have the same basic structure, template methodology, and can easily ingest new classes that I create.
However, I ran into a problem that I did not think far enough ahead to avoid, partly because OOP is rusty for me. alot of the files depend on each other, which is fine because this is after all a framework, remove 1 brick and it falls down. I don't care about the arguments for or against this methodology, i care about the correctness of execution of it.
This is going to be a bit difficult to describe, but I am going to post the relevant chunks and we will see how it goes i guess.
The real question is at the end of the post.
somepage.php - this is the page that gets hit by the surfer. There will be a few of these, 1 for each pagetype of the site.
<?php
require_once('classes/_binder.php'); //includes ALL my classes
//messages
$messages = new messages(); //create the messages object for displaying errors and messages
//Security.
$security = new security(); //create the security object
$security->overridemagicquotes(); //undoes the stupid magic quotes function to fix database issues.
//$security->bounceto = 'http://www.somesite.com/login.php'; //where to send denied users
//$security->validusertypes = 'admin,user,guest'; //allowed usertypes
//$security->enforcepagesecurity(); //this is the page level enforcement.
$template = new template(); //create the template object
$template->templatefile = 'templates/maintemplate.php';
$template->metatitle = 'TITLE HERE';
$template->metakeywords = 'KEYWORDS HERE';
$template->metadescription = 'DESCRIPTION HERE';
$template->stylepath = '/styles.css';
//1st page specific content gets generated into a STRING
$template->pagecontent = <<<CONTENT
content goes here. remember to wrap objects and such in {}
{$security->HTMLsafe('this is a <test>')}
CONTENT;
//2nd the template gets executed, with the page specific STRING dropped into place
require_once($template->templatefile); //loads the template for this page. which also runs PageContent below.
echo $fullpage; //this var is the result from the template file
?>
maintemplate.php - just an example of a template file, which is used by the page above. this is my personal pref for methodology, since I hate header/footer template splitting.
<?php
$fullpage = <<<TEMPLATEHTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>{$template->metat}</title>
<meta name="description" content="{$template->metad}">
<meta name="keywords" content="{$template->metak}">
<link href="{$template->stylepath}" rel="stylesheet" type="text/css">
</head>
<body>
<div>
{$template->menuitem('<a href="index.php">Home</a>','')}
{$template->menuitem('<a href="someadminpage.php">admin</a>','admin')}
</div>
<div>{$messages->showmsg()}</div>
<div>{$messages->showerr()}</div>
<div>{$template->content()}</div>
</body>
</html>
TEMPLATEHTML;
?>
security.class.php - this is the beginning of my security class, not just for user logins, but for site security issues like injections as well. This is the class that has caused me a problem because I know my execution is bad.
<?php
/*
depends on:
messages.class.php
*/
class security
{
public $bounceto; //Where to send the user upon NOT AUTHORIZED
public $validusertypes; //valid usertypes for the page. comma seperated
public function enforcepagesecurity()
{
if (strlen($this->validusertypes)>0) //then there is security to enforce
{
if (array_search($_SESSION['usertype'],array($this->validusertypes))===false)
{
//HERE IS THE PROBLEM - global gives me the willies and creates a dependency on another class being instantiated to work.
global $messages;
if (strlen($_SESSION['usertype'])>0)
{
$messages->adderr('You are not authorized for the page '.$this->HTMLsafe($_SESSION['PHP_SELF']));
header('Location:'.$this->bounceto);
}
else
{
$messages->adderr('You are not logged in and cannot access the page '.$this->HTMLsafe($_SESSION['PHP_SELF']));
header('Location:'.$this->bounceto.'?from='.urlencode($_SESSION['PHP_SELF']));
}
}
}
}
//CLIPPED some methods that are not necessary for show and tell.
}
?>
My methodology is that I use a session variable to store errors and messages for eventual display to the user. This is simpler to deal with in my mind because in a site where the user might bounce through a couple of pages before finally getting a rendered page, such as redirecting because they are not logged in, the errors accumulate, and I can display them all on the final page, as a part of the template. Sure I could store it in a property of the class, and pass it along with each request, but that makes for ugly URLs, and can have limitations.
So the problem is that message object. Since I am inside the security object, the message object which was instantiated on the somepage.php is not in scope. The easy way I found is to just global $message, and it all works. I also can create a brand new message object inside the security class, and just keep adding errors to the session object, because the session object is global by default, accessible anywhere. However, that also seems wrong to me.
I also tried EXTENDS on the security class, extending the message class, but that won't work as a real solution because if I ever need a second class accessible inside the security class, I would be back to global being needed again. (if that makes sense)
So what are the thoughts on this? Is using global OK in this case? Since I know that EVERY TIME there will be a $messages object floating around at the root scope, or is there another way that I am missing?