0

I am working on a custom framework and have a couple of questions about parent class instantiation through child classes.

I will paste some code snippets and then get into the questions

class CFrameWork {

    private $applicationName = "Application Name";

    function __construct($instance = "development") {
        echo "Hello, I am the Parent and I have been constructed<BR />";
    }

    public
    function startApplication() {
        $this->checkMaintenanceMode();
        if (!isset($_GET['query'])) {
            $this->intialize();
        } else {
            // Call the appropriate controller
            // Method and function are pulled from the query
            // Code not displayed
            // EDITS BELOW

            if (method_exists($method, $function)) {
                try {
                    call_user_func(array(new $method, $function), $this);
                } catch (CFException $exp) {
                    $this->show404();
                    exit;
                }
            } else {
                $this->show404();
                exit;
            }
        }
    }

}

Next we have a controller class

class childController extends CFrameWork {

    function index() {
        echo "Index Controller";
    }

    function register() {
        echo "Registration Controller";
    }
}

Now in the index.php, I have

$application = new CFrameWork();
$application->startApplication();

The way this Framework interprets queries:

localhost/childController/index - Calls the index() function in class childController localhost/childController/register - Calls the register() function in class childController

and so on...

So here's my concern. The parent class in this framework in instansiated twice each time a controller method is called. Once by the index.php (where the initial application is created) and then by the controller when it is extended. IN other words, CFrameWork::__construct() is created again everytime a controller method is reached.

My questions:

1) Does this have any harmful effect?

2) Can this be avoided?

3) Any suggestions on how you would do this differently?

Rohit Chopra
  • 2,791
  • 4
  • 28
  • 33
  • 1
    Did you search for singleton OOP patterns? – Taha Paksu Mar 22 '12 at 14:12
  • 1
    Your controller probably shouldn't extend a class that starts the application, but a master controller class instead. – jeremyharris Mar 22 '12 at 14:15
  • 3
    Just by itself, `class childController extends CFrameWork` has a bad code smell. A controller [IS-NOT-A](http://en.wikipedia.org/wiki/Liskov_substitution_principle) framework, so why does it inherit from one? – Jon Mar 22 '12 at 14:18
  • @tpaksu , why would anyone intentionally search for antipatterns ? – tereško Mar 22 '12 at 17:44
  • 1
    @tereško, he asked "Can this be avoided" and I understood "if there's already one instance on the page, how would I avoid the second to be instantiated?" so my answer was like this. – Taha Paksu Mar 22 '12 at 19:21
  • @tpaksu http://stackoverflow.com/a/1020384/326016 and http://stackoverflow.com/a/138012/326016 – Abenil Mar 22 '12 at 19:31
  • I'm not arguing with you because I myself used singletons maybe once or twice in a project. But the answer for "how can I get 'the' apple and not buy a new one if I already have it?' is still containing the 'singleton' option. – Taha Paksu Mar 22 '12 at 19:38

2 Answers2

1

PHP applications only exist for a very short time:

  1. You go to a webpage.
  2. The script is interpreted and output is generated.
  3. The script exits.

That is the expected and recommended workflow of most scripting languages such as PHP. This means that every time you access a page, a new class has to be created, therefore the constructor will be called each time. So to answer your questions:

  1. Does this have any harmful effect?
    Generally, no. It's how it's supposed to work. Whether it might have a harmful effect for your application depends on exactly what you're doing in the constructor.

  2. Can this be avoided?
    This could be avoided using caching or serializing and saving the class instances, but I can't for the life come up with a good reason for why you would want this.

  3. Any suggestions on how you would do this differently?
    I wouldn't do it differently. It's how the Model-View-Controller pattern is supposed to work. Take a look at popular frameworks like Yii, CodeIgniter, CakePHP - they all do it like you.

kba
  • 19,333
  • 5
  • 62
  • 89
0

This is bad on several levels:

    • as Jon already pointed out, your object inheritance does not makes sense.
    • childController class has now two sets of responsibilities: taking actions and performing the routing, this is breaking SRP. They should be two completely separate classes.
  1. Create class that deals exclusively with routing. It will be the one which deals with $_GET['query']. Give that class a method getControllerName() .. or something and getControllerMethod(). Does not matter how you call them. What matters is that the result of thous methods you use to create the new Controller instance right there in the index.php and perform an action on that controller.

  2. Besides what's written in 2., you should learn what SOLID principles are, what Law of Demeter is, what is dependency injection. And only then try to make an MVC framework again.

Community
  • 1
  • 1
tereško
  • 58,060
  • 25
  • 98
  • 150
  • First, the child controller is not responsible for performing the routing. I have edited the code to make that clear. The purpose of all child classes are to render appropriate views. It will probably be clearer now. The reason I am extending the children from the parent is so that it can access variables like $applicationName, and several other variables. I appreciate constructive criticism, and I know exactly what LoD and DI mean. There is no need to be so rude. – Rohit Chopra Mar 22 '12 at 19:26
  • @RohitChopra , so what does the `startApplication()` do if not *perform the routing* ? And how exactly was I rude ? – tereško Aug 13 '12 at 20:06