Page 1 of 3

Dynamic Class

Posted: Wed Feb 08, 2006 7:26 pm
by xcom923
I was wondering if anyone knew how to dynamically create a class.

here is my idea. depending on what the class needs to do it'll open a file and assign functions to itself. doing this will hopefully reduce loading time since it won't load everything that can possible be done at once. Does this make sense??

Posted: Wed Feb 08, 2006 7:50 pm
by raghavan20
can you give us an example so we could think of ways how to do it and to see really it would be useful or what are the alternatives for it?

Re: Dynamic Class

Posted: Wed Feb 08, 2006 8:09 pm
by Christopher
xcom923 wrote:I was wondering if anyone knew how to dynamically create a class.
You can dynamically create classes in PHP using eval(). If you want me to post some mixin code I'd be glad to.
xcom923 wrote:here is my idea. depending on what the class needs to do it'll open a file and assign functions to itself. doing this will hopefully reduce loading time since it won't load everything that can possible be done at once. Does this make sense??
Not quite following that, nor do I think this is a performance idea in general.

Posted: Wed Feb 08, 2006 9:00 pm
by xcom923
OK this is what I mean. I usually get Queries from the URL. so lets say I say "?run=userCP" I'd want to have the class look in a file and register some functions to itself (being the class) I'm mainly doing this because it'll allow me to go though same classes without loading what I don't need.

the way I have to code is everything ultimately in one master class but loading an entire class for lets say I was doing a music system that adds URLs for music and displays a list of those same URLs as well as allows you to modify the URLs. I want to only load what the user is doing this way it'll save a little on loading time as well as server impact.

is that a little clearer??

Posted: Wed Feb 08, 2006 9:10 pm
by neophyte
I'm not sure I follow but I'll throw out an idea and see if it helps.

The query string tells you what folder/directory the class is stored in. But the class always has the same name. As long as the function does a similar thing, process form or something like that it might work out okay. I've seen this work out okay before.

Posted: Wed Feb 08, 2006 9:30 pm
by xcom923
not quite what I'm talking about. The class loads and it has a switch inside the autoloader function that reads the query and executes a function based on what the query is. What I'm looking for is a way for it to load up a file and assign the function before actually running it. that way since usually there are lots of possiblities I can cut down on the file size

Posted: Wed Feb 08, 2006 10:04 pm
by d3ad1ysp0rk
xcom923 wrote:not quite what I'm talking about. The class loads and it has a switch inside the autoloader function that reads the query and executes a function based on what the query is. What I'm looking for is a way for it to load up a file and assign the function before actually running it. that way since usually there are lots of possiblities I can cut down on the file size
Why not just use a basic MVC pattern?

Posted: Thu Feb 09, 2006 1:13 am
by John Cartwright
I do something similar to dynamically make calls to modules and such

Code: Select all

$moduleCall = new $controller;
$result = $moduleCall->{$requestMethod}();
as mentioned erlier, in combination with __autoload()

Posted: Thu Feb 09, 2006 2:29 am
by Christopher
xcom923, it sounds like you are talking about a Front Controller which centralize calling like that. It dispatches classes using the Command pattern. So your URL "?run=userCP" would load class named userCP, instansiate an object of that class, and then run $usercp->execute(). I think we can come up with some some examples of that.

Posted: Thu Feb 09, 2006 9:20 am
by xcom923
Jcart wrote:I do something similar to dynamically make calls to modules and such

Code: Select all

$moduleCall = new $controller;
$result = $moduleCall->{$requestMethod}();
as mentioned erlier, in combination with __autoload()
I know there is a way to assign a function to a class outside its declaration (but I can't find how to do it). What I want to do is simular to that but only inside the object. IE if I created a function like this
_______________

function foo(){
echo 'this is foo';
}

_______________

and the way to assign it inside a class call 'megaClass' is
_______________

$Obj = new megaClass();
$Obj->define_function('foo'); //I just made that the way to do it since I don't remember
_______________

what I'm trying to do is more like this

_______________

class megaClass{

function register($function = NULL){
if($function != NULL){
$This->define_function($function);
}
}
}

________________

does that help? the whole point is that I'll have the functions that would be assigned in a different file and include those files when I need them.

Posted: Thu Feb 09, 2006 9:29 am
by feyd
you're going to create a lot of headache for yourself going down this path.

Posted: Thu Feb 09, 2006 12:19 pm
by Christopher
I agree with feyd, you are trying to do something a certain way rather than understanding standard OOP methodology. For example with composition you can do something like this (PHP4 compatable code):

Code: Select all

class myClass{

function myClass(&$function){
    $this->myfunction = &$function;
}

function myFunction($arg){
    $this->myfunction($arg);
}

}
You can do trickier things in PHP but they usually cause more problems than they solve.

Posted: Thu Feb 09, 2006 12:51 pm
by xcom923
I understand standard OOP but I had an idea and just wasn't sure how to implement it. Now I'm caught on a different project but I still wanna try this out. the reason I'm doing this is mainly because I have to work with other code. the details are a little complicated but all in all arborint that snippet of code made me want to try something. I'll get back to you with the results

Posted: Thu Feb 09, 2006 1:32 pm
by Gambler
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.

Posted: Thu Feb 09, 2006 3:23 pm
by Christopher
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.
MVC has a number of connotations, but is often implemented with a Front Controller in PHP. In fact I think the Front Controller is probably the solution of choice for most enterprise type PHP coders. Here is an example:

Code: Select all

<?php
class FrontController{
var $action_dir;
var $default_action;
var $error_action;
var $action_param;
var $action = '';

function FrontController($action_dir='action', $default_action='home', $error_action='error', $action_param='action'){
    $this->action_dir = $action_dir;
    $this->default_action = $default_action;
    $this->error_action = $error_action;
    $this->action_param = $action_param;
}

function & commandFactory($action){
    $obj = null;
    $filename = $this->action_dir . $action . '.php';
    if (file_exists($filename)) {
        include($filename);
        if (class_exists($action)) {
              $obj =& new $action();
        }
    }
    return $obj;
}

function execute(){
    if (isset($_GET[$this->action_param])) {
         $this->action = preg_replace('/[^a-zZ-Z0-9\_\-]/', '', $_GET[$this->action_param]);
    } else {
         $this->action = $this->default_action;
    }
    $obj = & $this->commandFactory($this->action);
    if (! $obj) {
        $obj = & $this->commandFactory($this->error_action);
    }
    $obj->execute();
}

}
?>
Actions are separate files that each contain a class that has the same name as the base filename. This is an example of using convention to simplify implemetation. You need to specify two "pages" for the Front Controller: the default page that is displayed of no "page" is specified (like the index.php file for Apache) and an error "page" for when something goes wrong.

A Front Controller accepts URL in to form "www.mysite.com/controller.php?action=home" or if it in index.php just "www.mysite.com/?action=home" or with clean URLs it might be "www.mysite.com/home/".

Here are the other files (if you dump them all in a directory you should be able to see them work by passing various "?action=" params like 'home', 'page' or ''):

index.php (or some other name like controller.php)

Code: Select all

<?php
include 'FrontController.php';

$fc =new FrontController('./', 'home', 'error');
$fc->execute();
?>
A default page like home.php

Code: Select all

<?php
class home{

function execute(){
	echo 'Home';        
}

}
?>
An error page like error.php

Code: Select all

<?php
class error{

function execute(){
	echo 'Error';        
}

}
?>
A then "pages" for your site like page.php

Code: Select all

<?php
class page{

function execute(){
	echo 'Page';        
}

}
?>
You'll notice that the commands all conform to the Command pattern (that's the polymorphic part). Only the action you are requesting is loaded, so there is very little code overhead. Typically the directory containing all if the Action files is out of HTML space -- you are free to put it anywhere you want.

This code really should be expanded with a little better error handling, maybe plugabble Action Factories, Request and Response objects, etc. And adding a Service Locator object, that gets passed everywhere, to tie it all together would make it the basis of a complete framework.