Page 1 of 1

Makig a dynamic loading/unloading class

Posted: Fri Jun 02, 2006 7:10 pm
by MrPotatoes
i created a loader class within my system. it's not really nessessary but i wanted to fool around since i didn't feel like making a database object right now. it's 'working' i'm just missing a function or two and this would be more fun anyways lmao.

well another reason is because i'm trying to limit the amount of globals within the system and limit them to under 10 hoenstly. yes, the whole system is in classes and i know the hit i'm going to take but the nice and neat code makes me soooooo happy you don't even know.

ok, my loader class as it stands consists of just 1 function and 1 variable. i planned to make it more but this is where i need help.

this is the loader class

Code: Select all

<?php
          //[b]loader.php[/b]	
	class Loader
	{
		var $cached_vars = array();
		
		function load($name)
                 {
			global $load;
			$this->object = new $name();
                 }
		
	}
?>
you pass it the name of the class and it gets it for you and puts it into the class object variable. sweet

now in the index.php i have this:

Code: Select all

//[b]index.php[/b]
         include 'class.php';
	include 'loader.php';
	
	$load;
	$CI;
	
	$loader = new Loader();
	
	$loader->load("everything");
	
	$loader->object->thing();
this is the class that it's grabbing:

Code: Select all

//[b]class.php[/b]
class everything
{        
        function thing() 	{ echo 'thing'; }
}

now. this works like a charm. the problem is (so i think) is that php loads everything up right at runtime. and i do not want it to add all the files to memory that doesn't need to be there. i'm trying to be conservative here with my code (C background :D:D) and i want to tell it when to load and unload files/classes and whatever.

so, if i have both those includes it'll load them up and it's easy for it to know where to get the class names. which is awesome but also not so much at the same time IMO. i want to have functions in there that are specific for certain things. such as load the database object, or load a PHP tool or load the user information. you understand? i planned to work the whole system like this so i could also limit my include statements as well.

any ideas?

example load function

Code: Select all

function loadDatabaseObject()
{
// check which type of DB we are running.  from the config file
// goto the folder where the DB files are stored
// inlucde those files
}

function unloadDatabaseObject()
{
// unload whatever object we have in the class array variable.
}
thanx for your help. i'm not sure if this should be in a more appropriate area but i don't think it's that complex of an idea. well, for you guys :D

Posted: Sat Jun 03, 2006 10:56 am
by MrPotatoes
well, i've actually gotten alot of this done and as a matter of fact i think it's quite brilliant. the only problem here is that PHP does too much work for me and i'm not doing enough. my C background makes me completely paranoid about things being deleted and destroyed. as a matter of fact i'm realy unsettled right now as to how this is working in certain areas with the unset

i have it currently where i can unset the whole object or one at a time and i'm trying to unset just one at a time ad the whole object is unset at the end of the main script.

the problem is that i'm used to working with memory, pointers and all that crap and when i'm not destroying the class variables i get a little worried. i don't know of a way to test or check how and where and when PHP is doing things.

for instance i have that class called loader. in each variable it will load a certain class called 'thing'. that class variable is set to the newly instantiated object that i loaded with the loader function. i can call all the classes's functions and variables thru the loader classes' varables. (that's a mouthful and if you are following that line of 'pointers' i applaud you lmao!).

well the loaded class has it's own memory and variables and such and i want to unset those before i unset the loader class' variables without unsetting the whole object. taht would destroy my application.

question: how would i do that? or do i even need to bother? it seems that PHP handles all that for me but like i said, coming from C/C++ i'm used to having to destroy everything manually.

i'm really sorry is that is too much to read.

thank you

Posted: Sat Jun 03, 2006 12:03 pm
by Christopher
First about your memory question, PHP is a little counter-intuitive when coming from a language where memory allocation/deallocation is very important. In PHP, freeing memory is a little bit of a deception anyway. That's because even though you call unset() it does not mean that PHP will acutually deallocate that memory internally -- it will decide the best thing to do based on its internal rules. The reason for this is that PHP scripts are intended to run for a fraction of a second and then exit. That is a very different environment than long running programs.

In general, PHP programmers do not free memory unless they are repeatedly allocating large data structures.

As to your loader -- take a look at the Registry and Lazy Load patterns. A number of frameworks (Zend for example) implement loaders that you use as examples.

Posted: Sat Jun 03, 2006 3:28 pm
by MrPotatoes
well firstly i will say thank you for your reply and i will definatly look those up

secondly i will complain because i thought this was new to me and i was really excited about it lmao!

it's ok tho. can't be the best at everything

Cheers

Posted: Sat Jun 03, 2006 5:51 pm
by Christopher
MrPotatoes wrote:secondly i will complain because i thought this was new to me and i was really excited about it lmao!

it's ok tho. can't be the best at everything
No need to complain and stay excited. ;)

There is a lot all of us can learn, expecially about concepts that are fairly new to PHP like these. Please investigate further, look at some of the examples around (e.g. Zend.php in the Zend Framework) and post more code as you hone your design. We are all here to learn and you questions and contributions will help more people than you think by airing ideas.

I think there is a lot of interest in these forums about combining Registry and Lazy Load together. It is an easy way to implement Dependency Injection which if pretty cutting edge in PHP. It would be great so see the various solutions people have come up with to solve this problem.

One question I have is: what problem did you encounter that caused you to need to create the above solution?

Posted: Sat Jun 03, 2006 5:54 pm
by ok
If you want to save time inclding files, use this function:

Code: Select all

function requireOnce($file) {
  static $loaded;
  if (!isset($loaded[$file])) {
    require_once($file);
    $loaded[$file] = 1;
  }
}

Posted: Sat Jun 03, 2006 5:57 pm
by Christopher
But your requireOnce($file) function is just duplicating what require_once($file) does?

Posted: Sat Jun 03, 2006 6:02 pm
by ok
It's quicker then require_once!!! (require_once waste a lot of time on checking if the file already included)

Posted: Sat Jun 03, 2006 6:10 pm
by n00b Saibot
any type of benchmarking results to prove it?

Posted: Sat Jun 03, 2006 6:13 pm
by ok
I took it from gallery2 project, and they are experts!!! (http://gallery.menalto.com/)

Posted: Sat Jun 03, 2006 6:16 pm
by MrPotatoes
actually i over hauled it. here's the code more or less:

Code: Select all

class Loader
{
	var $library;

	function loadType($name)
        {
		$token 	= strtok($name, '.');
		$name 	= str_replace($token, '', $name);
		$name	= str_replace('.', '', $name);

		if (is_object($this->library[$name]))
			exit();

		include DEBUG.$token.'.'.$name.'.php';
		$this->library[$name] = new $name();
}
}
DEBUG is a system define running off of BASEDIR which is the system folder. i know i know, i rule ;)
all my files are named in a very speicifc format and that's why i'm doing that string truncate crap. took me a second too because i don't remember strings and i've always been weak in that area. always needing refreshing for that subject matter.

anyways, i have my system folders set up in a very specific format so i have quite a few of these functions which are basically all the same they just have a different area to include from. i could be more dynamic about it later but right now i dont feel like it.

this is what the code looks like when you are ready to use the loader:

Code: Select all

require_once CORE.'/core.loader.php';
	
	$load = new loader();
	$load->loadTYpe('debug.ErrorLogging');
	
	$load->library['ErrorLogging']->throwError('heading', 'message');
so now i can call it from the array name in the loader class. you can also do it this way:

Code: Select all

require_once CORE.'/core.loader.php';
	
	$load = new loader();
	$load->loadTYpe('debug.ErrorLogging');
	
	$error = $load->library['ErrorLogging']->throwError('heading', 'message');
	$error->throwError('heading', 'message');
so from then on you just call error and it makes your code alot cleaner. that is unless you are like me. i can take the longer names. i actually prefer it so i don't get confused later on.

feel free to use this code. i personally think it's badass :D