Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9255963
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 18, 20262026-06-18T11:49:46+00:00 2026-06-18T11:49:46+00:00

I am attempting to refactor my app using the MVC paradigm. My site displays

  • 0

I am attempting to refactor my app using the MVC paradigm.

My site displays charts. The URLs are of the form

  • app.com/category1/chart1
  • app.com/category1/chart2
  • app.com/category2/chart1
  • app.com/category2/chart2

I am using Apache Rewrite to route all requests to index.php, and so am doing my URL parsing in PHP.

I am working on the enduring task of adding an active class to my navigation links when a certain page is selected. Specifically, I have both category-level navigation, and chart-level sub-navigation. My question is, what is the best way to do this while staying in the spirit of MVC?

Before my refactoring, since the nav was getting relatively complicated, I decided to put it into an array:

$nav = array(
  '25th_monitoring' => array(
    'title'    => '25th Monitoring',
    'charts' => array(
      'month_over_month' => array(
        'default' => 'month_over_month?who=total&deal=loan&prev='.date('MY', strtotime('-1 month')).'&cur='.date('MY'),
        'title'   => 'Month over Month'),
      'cdu_tracker' => array(
        'default' => 'cdu_tracker',
        'title'   => 'CDU Tracker')
    )
  ),
  'internet_connectivity' => array(
    'title'   => 'Internet Connectivity',
    'default' => 'calc_end_to_end',
    'charts' => array(
      'calc_end_to_end' => array(
        'default' => 'calc_end_to_end',
        'title' => 'calc End to End'),
      'quickcontent_requests' => array(
        'default' => 'quickcontent_requests',
        'title' => 'Quickcontent Requests')
    )
  )
);

Again, I need to know both the current category and current chart being accessed. My main nav was

<nav>
  <ul>
    <?php foreach ($nav as $category => $category_details): ?>
    <li class='<?php echo ($current_category == $category) ? null : 'active'; ?>'>
      <a href="<?php echo 'http://' . $_SERVER['SERVER_NAME'] . '/' . $category . '/' . reset(reset($category_details['charts'])); ?>"><?php echo $category_details['title']; ?></a>
    </li>
    <?php endforeach; ?>
  </ul>
</nav>

and the sub-nav was something similar, checking for current_chart instead of current_category.

Before, during parsing, I was exploding $_SERVER['REQUEST_URI'] by /, and breaking the pieces up into $current_category and $current_chart. I was doing this in index.php. Now, I feel this is not in the spirit of the font controller. From references like Symfony 2’s docs, it seems like each route should have its own controller. But then, I find myself having to define the current category & chart multiple times, either within the template files themselves (which doesn’t seem to be in the spirit of MVC), or in an arbitrary function in the model (which would then have to be called by multiple controllers, which is seemingly redundant).

What is the best practice here?

Update: Here’s what my front controller looks like:

// index.php
<?php
// Load libraries
require_once 'model.php';
require_once 'controllers.php';

// Route the request
$uri = str_replace('?'.$_SERVER['QUERY_STRING'], '', $_SERVER['REQUEST_URI']);
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && (!empty($_GET)) && $_GET['action'] == 'get_data') {

  $function = $_GET['chart'] . "_data";
  $dataJSON = call_user_func($function);
  header('Content-type: application/json');
  echo $dataJSON;

} elseif ( $uri == '/' ) {
  index_action();

} elseif ( $uri == '/25th_monitoring/month_over_month' ) {
  month_over_month_action();

} elseif ( $uri == '/25th_monitoring/cdu_tracker' ) {
  cdu_tracker_action();

} elseif ( $uri == '/internet_connectivity/intexcalc_end_to_end' ) {
  intexcalc_end_to_end_action();

} elseif ( $uri == '/internet_connectivity/quickcontent_requests' ) {
  quickcontent_requests_action();

} else {
  header('Status: 404 Not Found');
  echo '<html><body><h1>Page Not Found</h1></body></html>';   
}

?>

It seems like when month_over_month_action() is called, for instance, since the controller knows the current_chart is month_over_month, it should just pass that along. This is where I’m getting tripped up.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-18T11:49:47+00:00Added an answer on June 18, 2026 at 11:49 am

    Well, I had almost the same trouble when was writing CMS-like product.
    So I’ve spend some time trying to figure out how to make this work and keep the code more maintainable and clean as well.
    Both CakePHP and Symfony route-mecanisms have a bit inspired me but it wasn’t good enough for me.
    So I’ll try to give you an example of how I do this now.

    My question is, what is the best way to do this while staying in the
    spirit of MVC?

    First, In general, best practice is NOT TO USE procedural approach with MVC in web development at all.
    Second, keep the SRP.

    From references like Symfony 2’s docs, it seems like each route should
    have its own controller.

    Yeah, that’s right approach, but it doesn’t mean that another route match can’t have the same controller, but different action.

    The main disadvantage of your approach (code that you have posted) is that you mix responsibilities and you’re not implementing MVC-inspired pattern.
    Anyway, MVC in PHP with procedural approach is just a horrible thing.

    So, what exactly you are mixing is:

    • Route mechanism logic (It should be another class) not in a “controller” and route map as well
    • Request and Response responsibilites (I see that it isn’t obvious to you)
    • Class autoloading
    • Controller logic

    All those “parts” should have one class. Basically, they have to be included in index or bootstrap files.

    Also, by doing so:

    require_once 'controllers.php';

    You automatically include ALL controllers per match (even on no-match). It actually has nothing to do with MVC and leads to memory leaks.
    Instead, you should ONLY include and instantiate the controller that matches against URI string.
    Also, be careful with include() and require() as they may lead to code duplication if you include the same file somewhere twice.

    And also,

    } elseif ( $uri == '/' ) {
      index_action();
    
    } elseif ( $uri == '/25th_monitoring/month_over_month' ) {
      month_over_month_action();
    
    } elseif ( $uri == '/25th_monitoring/cdu_tracker' ) {
      cdu_tracker_action();
    
    } elseif ( $uri == '/internet_connectivity/intexcalc_end_to_end' ) {
      intexcalc_end_to_end_action();
    

    It’s extremely unwise to do a match using if/else/elseif control structures.
    Okay, what if you have 50 matches? or even 100? Then you need to write 50 or 100 times to write else/elseif accordingly.
    Instead, you should have a map and (an array for example) iterate over it on each HTTP request.

    The general approach of using MVC with routing mechanism comes down to:

    1. Matching the request against route map (and keep somewhere parameters if we have them)
    2. Then instantiate appropriate controller
    3. Then pass parameters if we have them

    In PHP, the implementation would look like:

    File: index.php

    <?php
    
    //.....
    
    // -> Load classes here via SPL autoloader or smth like this
    
    // .......
    
    // Then -> define or (better include route map from config dir)
    
    $routes = array(
    
        // -> This should default one
        '/' => array('controller' => 'Path_To_home_Controller', 'action' => 'indexAction'),
    
        '/user/:id' => array('controller' => 'Path_to_user_controller', 'action' => 'ViewAction'),   
    
        // -> Define the same controller
        '/user/:id/edit' => array('controller' => 'Path_to_user_controller', 'action' => 'editAction'),
    
    
        // -> This match we are going to hanlde in example below:
        '/article/:id/:user' => array('controller' => 'SomeArticleController', 'action' => )
    
    );
    
    // -> Also, note you can differently handle this: array('controller' => 'SomeArticleController', 'action' => )
    // -> Generally controller key should point to the path of a matched controller, and action should be a method of the controller instance
    // -> But if you're still on your own, you can define it the way you want.
    
    
    // -> Then instantiate common classes
    
    $request  = new Request();
    $response = new Response();
    
    $router = new Router();
    
    $router->setMap( $routes );
    
    // -> getURI() should return $_SERVER['REQUEST_URI']
    $router->setURI( $request->getURI() ); 
    
    
    if ( $router->match() !== FALSE ) {
    
      // -> So, let's assume that URI was:  '/article/1/foo'     
    
      $info = $router->getAll();
    
      print_r ( $info );
    
      /**
       * Array( 'parameters'  =>  Array(':id' => '1', ':user' => 'foo'))
       *        'controller'  => 'Path_To_Controller.php'
       *        'action'      => 'indexAction'
       */
    
       // -> The next things we are going to do are:
    
       // -> 1. Instantiate the controller
       // -> 2. Pass those parameters we got to the indexAction method   
    
       $controller =  $info['controller'];
    
       // -> Assume that the name of the controller is User_Controller
       require ( $controller ); 
    
       // -> The name of class should also be dynamic, not like this, thats just an example
       $controller = new User_Controller(); 
    
       $arguments = array_values( $info['parameters'] );
    
       call_user_func_array( array($controller, $info['action']), $arguments );  
    
       // -> i.e we just called $controller->indexAction('1', 'foo') "dynamically" according to the matched URI string
    
       // -> idealy this should be done like: $response->send( $content ), however
    
    } else {
    
       // -> In order not to show any error
       // -> redirect back to "default" controller
       $request->redirect('/');
    
    }
    

    In my MVC-inspired applications I do route like this:

    (Where I use Dependecy Injection and keep the SRP)

    <?php
    
    require (__DIR__ . '/core/System/Auload/Autoloader.php');
    
    Autoloader::boot(); // one method includes all required classes
    
    $map = require(__DIR__ . '/core/System/Route/map.php');
    
    $request    = new Request();
    $response   = new Response();
    
    $mvc        = new MVC();
    $mvc->setMap( array_values($map) ); 
    // -> array_values($map) isn't accurate here, it'd be a map of controllers
    // -> take this as a quick example
    
    
    $router     = new Router();
    
    $router->setMap( $map );
    $router->setURI( $request()->getURI() );
    
    
    if ( $router->match() !== FALSE ) {
    
        // -> Internally, it would automatically find both model and view instances
        // -> then do instantiate and invoke appropriate action
        $router->run( $mvc );
    
    } else {
    
        // No matches handle here
        $request->redirect('/');
    }
    

    I found this to be more appropriate for me, after poking around Cake and Symfony.

    One thing I want to note:

    It’s not that easy to find good articles about MVC in PHP. Most of them are just wrong.
    (I know how it feels, because first time I’ve started to learn from them, like so many people do)

    So my point here is:

    Don’t make the same mistake like I did before. If you want to learn MVC, start doing this by reading
    Zend Framework or Symfony Tutorials. Even the ones are bit different, the idea behing the scene is the same.

    Back to the another part of the question

    Again, I need to know both the current category and current chart
    being accessed. My main nav was

    <nav>
      <ul>
        <?php foreach($nav as $category => $category_details): ?>
        <li class='<?php echo ($current_category == $category) ? null : 'active'; ?>'>
          <a href="<?php echo 'http://' . $_SERVER['SERVER_NAME'] . '/' . $category . '/' . reset(reset($category_details['charts'])); ?>"><?php echo $category_details['title']; ?></a>
        </li>
        <?php endforeach; ?>
      </ul>
    </nav>
    

    First of all, don’t concatenate the string, instead use printf() like:

    <a href="<?php printf('http://%s/%s/%s', $_SERVER['SERVER_NAME'], $category, reset(reset($category_details['charts']))); ?>"><?php echo $category_details['title']; ?></a> 
    

    If you need this to be everywhere (or at least in many different templates), I’d suggest to this to have in a common abstact View class.

    For example,

    abstract class View
    {
        // -> bunch of view reusable methods here...
    
        // -> Including this one
        final protected function getCategories()
        {
            return array(
    
                //....
            );
        }
    }
    
    class Customers_View extends View
    {
        public function render()
        {
            $categories =& $this->getCategories();
    
            // -> include HTML template and then interate over $categories
        }
    
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've been attempting to refactor a fairly simple three or four page site to
Attempting to change the files folder location in a Drupal site from /files to
I inherited a Flash CS3 legacy app and I am trying to refactor it
Attempting to follow this project http://thepseudocoder.wordpress.com/2011/10/04/android-tabs-the-fragment-way/ When I run it, it says everything installs
Attempting to set up Samba + OpenLDAP using nss_ldap. After joining Windows7 to Samba
Attempting to load in multiple js libraries. Using either method bellow, the bootstrap and
I am trying attempting to refactor the following code: public static void SaveSplitbar(RadSplitBar splitBar)
Attempting to use asp.net mvc's Action Result of File. So it would seem that
attempting a first Blackberry App. It will display diary data (eventually). I'm just trying
I'm a rails newbie attempting to make an app for managing translations of sets

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.