Jump to content

MVC Framework - Trying to add to singleton


stuartmarsh

Recommended Posts

I'm trying to create a small H-MVC framework and I am hitting a snag.

This is how I want it to work:

  • All controllers extend a base class
  • You can load additional controllers from within an already called controller (H-MVC), and call them like $this->controller

I'm using a singleton to add classes to already loaded controllers, but I hit an error when I try to use a function from a loaded controller.

Here is the code.  Core.php is loaded first.

Core.php:

<?PHP 
define(EXT, '.php');

function & load_library($library, $params = array(), $instantiate = TRUE)
{
static $libraries = array();

if( !isset($libraries[$library]) )
{
	if( $instantiate == TRUE )
	{
		$libraries[$library] =& new $library($params);
	}
}

return $libraries[$library];
}

class Load
{
function & controller($Controller, $Params = array(), $load = TRUE)
{
	static $Controllers = array();

	require_once($Controller.EXT);
	$Controllers[$Controller] =& new $Controller($Params);

	$base =& get_instance();
	$base->$Controller =& $Controllers[$Controller];

	return $Controllers[$Controller];
}
}

$Load =& load_library('Load');

$Load->controller('Controller', array(), FALSE);

$controller =& $Load->controller('welcome', array(), FALSE);
$controller->index();

?>

 

Controller.php:

<?PHP 
class Controller 
{
private static $instance;

function __construct()
{
	self::$instance =& $this;		
	$this->load =& load_library('load');
}

public static function &get_instance()
{
	return self::$instance;
}
}

function &get_instance()
{
return Controller::get_instance();
}
?>

 

welcome.php

<?PHP 
class Welcome extends Controller
{
function __construct()
{
	parent::__construct();
}

function index()
{
	$this->load->controller('Cont2');
	$this->Cont2->admin(); // THIS IS WHERE IT ERRORS
}

}
?>

 

cont2.php:

<?PHP 
class Cont2 extends Controller
{
function __construct()
{
	parent::__construct();
}

function admin()
{
	echo "This is a sub controller<br />";
}	
}
?>

 

Can anybody see why I am hitting an error when trying to call the admin function from within the welcome controller?

 

Thanks,

Stu

Link to comment
Share on other sites

You might want to create some public/protected/private variables inside some of your classes...

You're calling $this->load , which doesn't actually exist (as far as I can see).

You also have some naming inconsistencies, you call the classes things like 'Welcome' and 'Load' and yet you store their names in arrays in lower case like 'welcome' and 'load' ... which is it?

 

It all looks a little crazy to me, can you explain in plain text what you're trying to achieve?

Link to comment
Share on other sites

You might want to create some public/protected/private variables inside some of your classes...

You're calling $this->load , which doesn't actually exist (as far as I can see).

You also have some naming inconsistencies, you call the classes things like 'Welcome' and 'Load' and yet you store their names in arrays in lower case like 'welcome' and 'load' ... which is it?

 

It all looks a little crazy to me, can you explain in plain text what you're trying to achieve?

 

Very good point with the $this->load.  I see where he tries to load it, but it's not actually set as a class property.  Add a declaration for it.

Link to comment
Share on other sites

Your first file will not work correctly and should trigger a error ( you are trying to load the class with the incorrect naming ) welcome and Welcome will be read as two different things.

 

The controller class should be setup as a abstract class

 

function __construct()

{

parent::__construct();

}

 

there is no need to call this again in a second class that is a child of your controller as it is already there.

 

when you are trying to load the Cont2 class you are calling $this->load it need to be $this->Load->controller().

 

And for your instance var try changing your code for the get_instance() function to the following

 

protected static $instance = __CLASS_NAME__;

 

function get_instance()

{

    return is_object(self::$instance) ? self::$instance : (self::$instance = new self::$instance());

}

 

and try running this hope this helps :) GL With OOP~~

Link to comment
Share on other sites

could not edit my post....

 

here is a better example I whipped up to show you.

 

<?php

class SessionAbstractInit
{
    protected static $instances = __CLASS__;
    
    public function Parse_All()
    {
        echo 'Parse All';
    }
    
    public function getInstance()
    {
        return (is_object($instances)) ? self::$instances : (self::$instances = new self::$instances);
    }
}

abstract class SessionAbstract extends SessionAbstractInit
{
    protected static $Init;
    
    public static $method;
    
    public function __construct()
    {
        self::$Init = SessionAbstractInit::getInstance();
            
        // This will hold the objects of $Init
    }
    
    public function print_stuff()
    {
       
    }
}

class Session extends SessionAbstract
{
    protected static $instance = __CLASS__;
    
    public function getInstance()
    {
        return (is_object($instance)) ? self::$instance : (self::$instance = new self::$instance);
    }
    
    public function donothing()
    {
        echo '<br /> Do Nothing!!';
    }
}


class SessionManagement
{
    public function __construct()
    {
        // create instance of session
        
        $this->session = Session::getInstance();
    }
    
    public function show()
    {
        $this->session->Parse_All();
        
        $this->session->donothing();
    }
}

$session = new SessionManagement();

$session->session->Parse_All();
$session->session->donothing();

$session->show();
?>

 

as you can see i created the abstract session which didn't do anything but in turn could load the class objects and turn them into a registry, and then branched two child classes off of it Session And SessionManagement.

SessionManagement loaded itself contained its getinsance and a donothing function, Session Loaded everything together into one object $this->session which held the values for all the parent classes before it.

 

You can see from this that you could easily modify in a loader function that will automatically load all classes into a single object in which you are trying to do :)

Link to comment
Share on other sites

If you want to know what he's trying to do, he's trying to copy the structure of CodeIgniter. (I know because I use it) :)

Thats exactly right.  I'm trying to create a framework that works the same way as CodeIgniter.

However unlike CodeIgniter, I want to be able to call controllers from within controllers.

Something that seems to be frowned upon on the CodeIgniter forums.

I also currently use CodeIgniter btw.

Link to comment
Share on other sites

have something like this as a base controller...

 

class Controller {
private $instances;
function __get($key) {
return $this->instances[$key];
}
function __set($key, $value) {
$this->instances[$key] = $value;
}
}

 

Then you can use something like this...

 

$this->cont2 = new cont2;

$this->cont2->admin();

 

Or, create another function specifically for using the __set() or doing the same thing.

 

----------------

Now playing: Burden of a Day - For Tomorrow We Die

via FoxyTunes

Link to comment
Share on other sites

afaik instead of using all the references (which also afaik is redundant since objects are passed by reference anyways).... although this is a generic example and doesn't really apply to the specifics of your project, here's a good example of a singleton implementation:

 

class Singleton {

private static $instance = null;

private function __construct(){}

    public static function getInstancia() {
    	if (self::$instance == null) {
    		self::$instance = new self();
    	}
    	return self::$instance;
    }
}

 

hope this helps :)

Link to comment
Share on other sites

afaik instead of using all the references (which also afaik is redundant since objects are passed by reference anyways).... although this is a generic example and doesn't really apply to the specifics of your project, here's a good example of a singleton implementation:

 

class Singleton {

private static $instance = null;

private function __construct(){}

    public static function getInstancia() {
    	if (self::$instance == null) {
    		self::$instance = new self();
    	}
    	return self::$instance;
    }
}

 

hope this helps :)

 

Hi alexweber15,

Thanks for the suggestin but if you look at the controller.php it already uses this method.  It fails to work when you extend the controller class more than once.

I have been playing with LemonInfluxes code and it does the job nicely.

Link to comment
Share on other sites

Hey, just to make sure we're talking about the same things here... when you say Controller.php do you mean Lemon's example or yours?

 

Also, as a conceptual/generic side-note:

Singletons should have a private constructor (or in your case maybe protected since you want to extend from it) and all the interaction to $instances should be done via a getInstance() function... but really, extending a Singleton is kind of um, contradictory in a way... :)

Link to comment
Share on other sites

good to know :)

 

an observer is a bit (lot) more complicated... :)

 

 

 

lol. Just starting to investigate it.

It sounds like you've got experience with it.  Any hints and tips?

 

 

to say ive got experience with it is a complete overstatement :)

ive been studying design patterns intensely for the past few weeks and have received a lot of help from ppl here on the boards (and many others) and from professors at uni so ive got at least concepts and theoretical implementations down, kind of :)

 

im at work right now so i gotta be kinda brief, but check these links out, they are really helpful! :)

 

http://en.wikipedia.org/wiki/Observer_pattern

http://www.fluffycat.com/PHP-Design-Patterns/Observer/

http://devzone.zend.com/article/5-PHP-Patterns-The-Observer-Pattern

 

also there's a ton of published literature on the subject, my favorites being:

- "The Gang of Four: Design Patterns, Elements of Reusable OO Software"

- "Architect's guide to php design patterns"

 

ill leave the details and ethics of how to obtain them up to you :)

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.