Page 3 of 3

Re: Single index.php or Multiple Script

Posted: Sat Apr 22, 2006 12:52 pm
by Christopher
AKA Panama Jack wrote:If you are NOT using a CMS backend then using a monolithic index.php is going to be detrimental in the long run. It really is considerably harder to debug, expand and track down issues that may arise. You would be better off sectioning out every page into seperate page files. This will make it considerably easier to maintain and upgrade.
This is an erroneous statement to equate an an application type, expecially a one with a million meanings like CMS, with an internal architecture decision like this. A "CMS" does not do anything unique that any other website does not do.
AKA Panama Jack wrote:Search engines tend to spider seperate pages with different names while ignoring pages that have the same name referenced through many get/post variables.
Using clean URLs with a Front Controller produces probably the most search engine friendly site without having to add directory/index.php pairs everywhere.

Posted: Sat Apr 22, 2006 1:22 pm
by alex.barylski
Jcart wrote:
AKA Panama Jack wrote:I would always stay away from monolithic index.php files as they will cause more harm than good. Plus they take up alot of server resources for no good reason loading and compiling all that unused code. You should only load what is needed for that page and nothing else
I don't see that being true at all. There is always very little or even no code (at least in my applications) that will be loaded that won't be used. Could you please elaborate on this?

Aside from this, don't you find it kind of ugly to include the same sections of code in multiple different files? Isn't that, to an extent, a bad design?
Both have their ups and downs...

On one hand, a single index.php does allow common application wide funcitonality to be easily shared through out, making code more readable, etc...

However, at the same time...using an index.php can cause code which is unnessecary to be parsed, etc...

For example, in my case (which in my situation is acceptable as my app is pretty small) I call upon several different views depending on a page selector variable...each of those views require different data...which sometimes require function calls...

If someone requests the login screen, there is no need for anything else to be parsed, etc...

I think is what he was getting at it...obviously there are work-arounds but how many developers get lazy and fail to use them, instead opting for a single large monolithic index.php? :P

Too many, especially if your clearly an optimization nutt like AKA PJ :P

Posted: Sat Apr 22, 2006 1:47 pm
by John Cartwright
If someone requests the login screen, there is no need for anything else to be parsed, etc...
Let me re-iterate myself, that just smells like a bad design if your having unecessary code called. I actually had similar problem the other day some code being called that shouldn't have always been.

In my case, it was my Views directly extended the template engine, and that to me is a big no no, considering it is not at all necesarry for a view to require a template engine. Then it got me thinking, what if the controller doesn't even require a view at all -- or even a model in that case? My point being that it was a miniscule amount of extra work, but I was able to come up with an effective way to deal with this. A good design should not be initializing stuff it does not use.

Posted: Sat Apr 22, 2006 2:45 pm
by Christopher
Hockey wrote:instead opting for a single large monolithic index.php? :P
I don't think anyone is talking about a "single large monolithic index.php." A Front Controller contains no application specific code -- it only contains application wide services such as routing, dispatch, access control, etc. My index.php files are pretty much identical from site to site, app to app.

Posted: Sat Apr 22, 2006 4:27 pm
by alex.barylski
Jcart wrote:
If someone requests the login screen, there is no need for anything else to be parsed, etc...
Let me re-iterate myself, that just smells like a bad design if your having unecessary code called. I actually had similar problem the other day some code being called that shouldn't have always been.

In my case, it was my Views directly extended the template engine, and that to me is a big no no, considering it is not at all necesarry for a view to require a template engine. Then it got me thinking, what if the controller doesn't even require a view at all -- or even a model in that case? My point being that it was a miniscule amount of extra work, but I was able to come up with an effective way to deal with this. A good design should not be initializing stuff it does not use.
So we all agree then :P

Posted: Sat Apr 22, 2006 4:33 pm
by John Cartwright
Hockey wrote:
Jcart wrote:
If someone requests the login screen, there is no need for anything else to be parsed, etc...
Let me re-iterate myself, that just smells like a bad design if your having unecessary code called. I actually had similar problem the other day some code being called that shouldn't have always been.

In my case, it was my Views directly extended the template engine, and that to me is a big no no, considering it is not at all necesarry for a view to require a template engine. Then it got me thinking, what if the controller doesn't even require a view at all -- or even a model in that case? My point being that it was a miniscule amount of extra work, but I was able to come up with an effective way to deal with this. A good design should not be initializing stuff it does not use.
So we all agree then :P
Not quite sure I follow. You were saying funneling all requests through the an index results code not being used on some requests, even though it was loaded. My point was disagreeing with that. Am I mistaken?

Posted: Sat Apr 22, 2006 6:22 pm
by Gambler
Personaly, I think using simgle frontend page is a good idea. In case of emergency you always have an option to manipulate input and output there.

Posted: Sat Apr 22, 2006 8:21 pm
by alex.barylski
Jcart wrote:
Hockey wrote:
Jcart wrote: Let me re-iterate myself, that just smells like a bad design if your having unecessary code called. I actually had similar problem the other day some code being called that shouldn't have always been.

In my case, it was my Views directly extended the template engine, and that to me is a big no no, considering it is not at all necesarry for a view to require a template engine. Then it got me thinking, what if the controller doesn't even require a view at all -- or even a model in that case? My point being that it was a miniscule amount of extra work, but I was able to come up with an effective way to deal with this. A good design should not be initializing stuff it does not use.
So we all agree then :P
Not quite sure I follow. You were saying funneling all requests through the an index results code not being used on some requests, even though it was loaded. My point was disagreeing with that. Am I mistaken?
A good design (regardless of implementation technique) should not be initializing anything it doesn't use - or parsing in the case of PHP.

Was the point I was getting at, in that we can all agree on...

Cheers :)

Posted: Sat Apr 22, 2006 8:54 pm
by Christopher
Hockey wrote:A good design (regardless of implementation technique) should not be initializing anything it doesn't use - or parsing in the case of PHP.
That is a one of many goals in developing PHP apps, but certainly 100% efficiency is not realistic. All PHP apps load some things that are not used on every page (configuration data for example). This is especially true for less used pages or error pages. A clean, clear design can have some inefficiency.

Posted: Sat Apr 22, 2006 9:39 pm
by John Cartwright
Ah yes, then we are in agreement.

Posted: Sun Apr 23, 2006 12:25 am
by alex.barylski
Ok so I thought I'd sit down for a few (thoughts not beer) and figure out MVC once and for all...

If I get it...I have seriously fallen victim to buzzword marketing...I thought there was alot more to it than what I just discovered...

I was convinced it was more a framework, than a design pattern as it's appears to solve those kind of problems or at least is touted as such...

Despite understanding the difference between a design pattern and an implementation of a MVC pattern I was subconsciencously convinced there was voodoo magic going like in many frameworks...

For the love of me, I couldn't visualize how three objects, which promoted separation of application parts could remain independant of each other and yet interact to yield a final result...

Mainly, I failed to see how that would be implemented at the lowest level, as thats how I try and learn things...I always work from the bottom up...I don't like just understanding the concept and using what been told to me until I fully understand it...

So here goes my current understanding of MVC (which is practically what i've been doing since I started PHP to one degree or another)...

Model or domain logic are completely independant of the other parts and can be implemented as classes or functions, doesn't matter, as all that is needed is the data returned...this was obvious...

The model is stable because unless your database schema changes or whatever else domain might use, the API doesn't change either...

Once you have a concrete design, your golden :P

The view, is NOT a template engine, but simple a wrapper around a template engine or other rendering device - by wrapper I'm not suggesting inheritence.

The view may be implemented as follows:

Code: Select all

class CxViewUser{
  function showUserList()
  {
    $domain = new CxModelUser();
    $arr_users = $domain->listUsers();

    $m_smarty->assign('arr_users', $arr_users);
    
    $smarty->display('user_list.tpl');
  }
}
As the above demonstartes, the view MUST have knowledge of the Model as it's what drives the view's view. :P

This makes the View slightly less stable than Model as any changes to the model, likely require changing the view as well.

Controller, this is the least stable as it has knowledge of both the View and the Model, so any changes to either may effect the controller as well.

The controller determines actions sent to it by user interaction, this can be implemented in any number of ways, one such method would be:

Code: Select all

switch($page){
  case 'new_user': // Controller uses MODEL
    $model = new CxModelUser();
    $model->createUser($_POST);
    break;
  case 'list_users': // Controller uses VIEW
    $view = new CxViewUser();
    $view->showUserList();
    break;
}
Because the above implements a dispatch mechanism which calls appropriate Model/View objects directly, this would be better described as a front controller?

Where as a controller *could be* an object like:

Code: Select all

class CxCtrlUser(){
  function createUser()
  {
    $model = new CxModelUser();
    $model->createUser($_POST);
  }
}

// And the front controller would then use the controller directly, like:

switch($page){
  case 'new_user': // Controller uses MODEL
    $ctrl = new CxCtrlUser();
    $ctrl->createUser();
    break;
}
The advantage of using controller objects as well is, now you can keep the front controller as clean as possible and code separation voila!!!

ie: Keeping model/view out of the front controller and letting it do it's dispatch work cleanly and clearly...

The dispatch work of a front controller is likely what MVC frameworks take care of for you???

As the other parts are likely to application specific to fit into a generic framework...

Anyways, what am I missing? Or is that the gist of it?

If thats it...it's waaay to over hyped...every article I read or thread for that matter pumped it's complexity to a point which made me not interested in pursuing any further, as my current approach to code separation is pretty much that...and got the job done!!!

I didn't see any benefits to switching, although, I can see now that a properly designed framework could make things a little clearer and easy to manage. :P

Cheers :)

Posted: Sun Apr 23, 2006 12:56 am
by John Cartwright
How I see it, the chain goes in this order

FrontController -> Controller -> View -> Model -> Data Access

Notice there is a seperation between the front controller and controller because they are completely different entities, that may be the source of your confusion.
The FrontController does not have any knowledge of views or models, it is simply there to decide which controller it wants to dispatch the action to (usually done through the URI) along with any other paramaters given.

Lets say the user visits /news/add

In my example, it goes /controller/action/namevalue1/pair2/namevalue2/pair2

our FrontController has all URI requests routed to it, although we arn't going to focus on that unless you want to. Now, the front controller recognizes that we want to involk a certain controller, the NewsController.. which is a common class for adding, removing, editing news.. you can go as far as to seperate each individual actions into their own controller if you need, although I tend to agglomerate similar utilities (some may disagree). Now the front controller should be aware of if the class exists, as well if the action called exists. If it doesn't, we don't want to dispatch to that controller, because we will obviously receive errors, so we want to redirect to a default controller and action. Typically, each controller has a default action, which the FrontController should call if no action was set.

Now that we have our controller dispatched,

Code: Select all

class NewsController extends ApplicationController
{
   public function __construct() 
   {
      $this->view = new NewsView();
   }

   public function AddAction()
   {
      if (!$this->isValidParam('blah') {
         $this->view->paintError('Invalid field blah');
      }
      
      $this->paintForm();
      $this->parseTemplate();
   }
}
Now I'm trying to keep this as simple as possible, but I want to show you the practical application of this. So our FrontControlelr has initiated this NewsController class, which I choose to have it extends an ApplicationController which handles common functionality of all controller, such as checking paramaters. Now, it could be you want to have a different method in your view called depending on certain paramaters sent, so the controller must determine what to do (business logic).

Code: Select all

class NewsView
{
   public function __construct() 
   {
      $this->model = new NewsModel();
      $this->template = new Template();
   }

   public function paintError($error)
   {
      $this->registerError($error);
      $this->template->setVar('error', $error);
   }
}
Now here we have our view, which is basically there to build our output, now that we know exactly what actions have been chosen to take. No more logic really takes place, except I find it acceptable to have very simple logic inside the view. Sometimes you need to pass paramaters to the views, such as an ID so you know what to give to the model -- so perhaps a simple check to make sure a value was passed or not can be allowed.

Code: Select all

class NewsModel
{
   public function __construct() 
   {
      //we only want 1 database connection right?
      $this->database = Registry::get('database');
   }

   public function registerError($error)
   {
      $sql = 'INSERT INTO ...`';
   }
}
Now we can have the model is responsible for the data, whether it is adding, editing, or deleting. My fingers hurt too much to type anymore! So I'll leave it at that.