Dynamic Class

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

d3ad1ysp0rk
Forum Donator
Posts: 1661
Joined: Mon Oct 20, 2003 8:31 pm
Location: Maine, USA

Post by d3ad1ysp0rk »

Gambler wrote:
Why not just use a basic MVC pattern?
MVC requires you to load and parse code for all methods in a class. So if you have contoller with 40 methods, you're parsing 40 methods, while using only one. I think, that's what xcom923 is talking about.
I guess my MVC's always use Front Controllers then. I rarely have code in a page that isn't used.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

d3ad1ysp0rk wrote:I guess my MVC's always use Front Controllers then. I rarely have code in a page that isn't used.
The question is whether you use a Front Controller or Page Controllers. If you only have one (or a few) controller scripts in your HTML directory then it is probably a Front Controller. If each page is a script then probably Page Controllers.
(#10850)
Gambler
Forum Contributor
Posts: 246
Joined: Thu Dec 08, 2005 7:10 pm

Post by Gambler »

Actions are separate files that each contain a class that has the same name as the base filename.
Here's what I do (this is highly simplified version of a real thing):

Code: Select all

class Prototype{
    var $module = '';
    
    function Prototype($name){
        $this->module = $name;
    }
    
    function &call($action, $args = NULL){
        if ($args == NULL) { $args = array(); }
        
        $result = &call_user_func_array(array($this, $action), array($args));
        
        return $result;
    }
}
Call is like your execute, but it executes arbitrary function inside the same class.

Code: Select all

class SomeModule extends Prototype{
    function home($args){
    }
    function error($args){
    }
}
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

This idea with Front Controller is to centralize common code. Usually it is a two level system where the Front Controller dispatches what are sometimes refered to as Input Controllers. They are similar to Page Controllers but are not their own entry point. Input Controllers are also polymorphic which can produce some benefits as the codebase gets larger.

The Front Controller can deal with the what you might call "page" level concerns like error handling and Access Control. For example, if you surveyed all of your Page Controllers and found that the error() methods are all similar then moving centralizing them into a Front Controller. The same with generalized Access Control such as "Is Signed-In" type checks where you want to deny access to a group or class of pages.

I have found that switching from Page Controllers to a Front Controller is usually a positive experience with a good amount of reduntant and crufty code removed.
(#10850)
xcom923
Forum Newbie
Posts: 22
Joined: Wed Feb 08, 2006 7:21 pm

Post by xcom923 »

interesting....but let me ask you this. How do you link an already defined function into a class?

I know

$this->myFunction = myfunction();


does not work. But I do know there is a way to do it but I deleted the source code I saw that in.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

from what I'm seeing, without php 5's magic method __call, you're going to need to use an interaction function and consider the internal variables callbacks.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

[quote="xcom923"]

Code: Select all

$this->myFunction = myfunction();
Does not work, but the following does:

Code: Select all

$this->my_class = new myClass();
On of the many benefits of objects is that you can pass them around like vars, but they have a type. You can pass around a string with a function name (or an array with a function name and args) to simulate what an object does -- but why not just use an object.
(#10850)
xcom923
Forum Newbie
Posts: 22
Joined: Wed Feb 08, 2006 7:21 pm

Post by xcom923 »

this may just be a lost cause but I wanted to add functions to the object because I've already seperated 4 levels of objects already and each object has gotten pretty big now and I need someway to only have the code loaded that will be used instead of having the huge object where only 10% of it will be used to generate the page. But if I don't figure this out it'll probably boil down to me doing the same thing but as classes IE

Code: Select all

class prototype{

   register($file,$name){
      require_once($file.'php');
      $exe = '$this->'.$name.' = new '.$file.'();';
      eval($exe);
   }
}
without just saving functions into the class I guess that's the closest thing I could do however how would I make variables inside the calling class accessible to the class that I created for the new variable (which is the reason I wanted to just add functions to the current class).
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

You would need to give the object access to those variables, either by passing in a reference to itself, or having accessors (preferred).

You could create a Fascade class that encapsulates the functions of the overall class and the component classes. It's certainly safer than hooking any random object that's called to register.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

xcom923 wrote:this may just be a lost cause but I wanted to add functions to the object because I've already seperated 4 levels of objects already and each object has gotten pretty big now and I need someway to only have the code loaded that will be used instead of having the huge object where only 10% of it will be used to generate the page.
This sounds like you have problems with your design. Symptoms like those are ususally called bad code smells. You probably have outgrown your current architecture and need to graduate to some some Controller based architecture like MVC.

In PHP I think you can just do the following without the need for the eval():

Code: Select all

class prototype{

   register($file,$name){
      require_once($file.'php');
      $this->$name = new $file();';
   }
}
I'd be interested in seeing a sample of your code, because it might be clearer what needs to be done.
(#10850)
xcom923
Forum Newbie
Posts: 22
Joined: Wed Feb 08, 2006 7:21 pm

Post by xcom923 »

thanks I didn't know that
User avatar
quocbao
Forum Commoner
Posts: 59
Joined: Sat Feb 04, 2006 2:03 am
Location: HCM,Vietnam
Contact:

Post by quocbao »

PHP5 and Overload may help you a lot :)
xcom923
Forum Newbie
Posts: 22
Joined: Wed Feb 08, 2006 7:21 pm

Post by xcom923 »

Gambler wrote:
Why not just use a basic MVC pattern?
MVC requires you to load and parse code for all methods in a class. So if you have contoller with 40 methods, you're parsing 40 methods, while using only one. I think, that's what xcom923 is talking about.
that's exactly RIGHT! and arborint I am using a pattern simular to that however my executing classes have become to big. The whole Idea of this came about since I wanted to only load what I'm going to use. I'm now trying to break it down even further, but I have the problem that certain things need to be loaded or functions shared between classes and I can't place 2 of those sepreate classes together since they would then become bigger...and I can't make them library files because they need to be inside the class....so where is what my next question is:


Is there a way to grab all variables in a class in some kind of list form? my next idea is to have a function built inside the controller class that will create a new class reference all it's own variables inside before executing the class.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

xcom923 wrote:
Gambler wrote:
Why not just use a basic MVC pattern?
MVC requires you to load and parse code for all methods in a class. So if you have contoller with 40 methods, you're parsing 40 methods, while using only one. I think, that's what xcom923 is talking about.
that's exactly RIGHT! and arborint I am using a pattern simular to that however my executing classes have become to big.
I guess I am wondering why you have code in your classes that does not pertain to the current "page." When using a Front Controller the "Action" class that is loaded are the just the Controller for the page. That Controller is page specific (though it may inherit common controller functionality from a base class) and in turn loads only what it needs. That is really the whole point of it.
xcom923 wrote:The whole Idea of this came about since I wanted to only load what I'm going to use. I'm now trying to break it down even further, but I have the problem that certain things need to be loaded or functions shared between classes and I can't place 2 of those sepreate classes together since they would then become bigger...and I can't make them library files because they need to be inside the class....so where is what my next question is:


Is there a way to grab all variables in a class in some kind of list form? my next idea is to have a function built inside the controller class that will create a new class reference all it's own variables inside before executing the class.
Perhaps you could post some example code so I would see what you are talking about.
(#10850)
xcom923
Forum Newbie
Posts: 22
Joined: Wed Feb 08, 2006 7:21 pm

Post by xcom923 »

arborint wrote:
xcom923 wrote:
Gambler wrote: MVC requires you to load and parse code for all methods in a class. So if you have contoller with 40 methods, you're parsing 40 methods, while using only one. I think, that's what xcom923 is talking about.
that's exactly RIGHT! and arborint I am using a pattern simular to that however my executing classes have become to big.
I guess I am wondering why you have code in your classes that does not pertain to the current "page." When using a Front Controller the "Action" class that is loaded are the just the Controller for the page. That Controller is page specific (though it may inherit common controller functionality from a base class) and in turn loads only what it needs. That is really the whole point of it.
Actually that's what's going on. the only problem is that the pages can be so dynamic depending on so many variables that the page can look completely different.
arborint wrote:
xcom923 wrote:The whole Idea of this came about since I wanted to only load what I'm going to use. I'm now trying to break it down even further, but I have the problem that certain things need to be loaded or functions shared between classes and I can't place 2 of those sepreate classes together since they would then become bigger...and I can't make them library files because they need to be inside the class....so where is what my next question is:


Is there a way to grab all variables in a class in some kind of list form? my next idea is to have a function built inside the controller class that will create a new class reference all it's own variables inside before executing the class.
Perhaps you could post some example code so I would see what you are talking about.
for example if I wanted to do something like

Code: Select all

function Run($class){
   include_once("folder".$class.".php");
   $system = new $class();
   $vars = getClassVars($this);  //this is where I've made up the function that gets all the variables in a class
   $count = 0;
   for($count=0; $count < count($vars); $count++){
      $system->$vars[$count] = $this->$vars[$count];
   }
   $system->autoRun();
}
does that help??
Post Reply