How to route requests in web applications?

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

Post Reply
bugrush
Forum Newbie
Posts: 15
Joined: Tue Dec 16, 2008 3:00 pm

How to route requests in web applications?

Post by bugrush »

What is a good way to route requests in php applications?
I keep my code/modules nested in my applications.

I use something like:

Code: Select all

 
$route = new RequestRoute('admin.php', 'r', @$_GET['r']);
$action = $route->next(array('menu', 'contents', 'galleries'));
 
if($action == 'menu') {
  require('admin/modules/menu.php');
} elseif($action == 'contents') {
  require('admin/modules/contents.php');
} elseif($action == 'galleries') {
  require('admin/modules/galleries.php');
} else {
  require('admin/modules/home.php');
}
 
and

Code: Select all

 
$action = $route->next();
if($action == 'insert') {
  if(isset($_POST['save'])) {
    //do some stuff
    header('Location: '.$route->url('..'));
  } else {
    //insert form
  }
} elseif($action == 'edit') {
  $product_id = (int)@$_GET['product_id'];
  if($product_record = $mysql->query('SELECT * FROM products WHERE id = "'.$product_id.'"')->fetch_assoc()) {
    $action = $route->next();
    if($action == 'pictures') {
      //edit, insert, sort, delete
    } elseif($action == 'details') {
      //form, saving
    } elseif($action == 'attachments') {
      //form, saving
    } else {
      if(isset($_POST['save']) {
        //save
      } else {
        //edit form
      }
    }
  } else {
    header('Location: '.$route->url('..'));
  }
} elseif($action == 'sort_order_up') {
 
} elseif($action == 'sort_order_down') {
 
} elseif($action == 'delete') {
 
} else {
  //list products
}
 
router code:

Code: Select all

 
class RequestRoute {
  var $_script;
  var $_key;
  var $_route;
  var $_pointer = 0;
  
  function __construct($script, $key, $route) {
    $this->_script = (string)$script;
    $this->_key = (string)$key;
    $route = (string)$route;
    if(!empty($route)) $route = explode('/', $route);else $route = array();
    $this->_route = array();
    foreach($route as $level) {
      if($level == '..') {
        array_pop($this->_route);
      } else {
        array_push($this->_route, $level);
      }
    }
  }
  
  function next($actions = array()) {
    if($this->_pointer < count($this->_route)) {
      $action = $this->_route[$this->_pointer];
      if(empty($actions) || in_array($action, $actions)) {
        $this->_pointer++;
        return $action; 
      }
    }
  }
  
  function url($route = '', $params = '') {
    $url = $this->_script;
    $get = '';
    $this_route = array();
    for($i = 0;$i < $this->_pointer;$i++) {
      array_push($this_route, $this->_route[$i]);
    }
    $route = (string)$route;
    if(!empty($route)) $route = explode('/', $route);else $route = array();
    foreach($route as $level) {
      if($level == '..') {
        array_pop($this_route);
      } else {
        array_push($this_route, $level);
      }
    }
    $this_route = implode('/', $this_route);
    if(!empty($this_route)) $get .= $this->_key.'='.$this_route;
    $params = (string)$params;
    if(!empty($params)) {
      if(!empty($get)) $get .= '&'.$params;
      else $get .= $params;
    }
    if(!empty($get)) $url .= '?'.$get;
    return $url;
  }
}
 
all urls look like this: index.php?r=products/edit/attachments/add&product_id=123&attachment_id=456
urls are generated with code: <?php echo $route->url('edit', 'product_id='.$product->id);?>

All this has few problems and I feel that I need to change it.
For example when my current location is 'products/edit/pictures' , I can't use just $route->url('..') anymore. I need to add 'product_id' everywhere. $route->url('..', 'product_id='.$product->id);

Also if($action == 'edit')if($product_record){$action = $route->next();/*another level of action switch*/}else{header('');/*go back*/} isn't very good idea when 'products/edit/pictures' is a tiny popup window. This kind of nesting doesn't work well. 'products/edit/pictures' should control what happens when the product_id is invalid(close the popup window and redirect main window using javascript).

I thought about giving each request an unique id and puting them into a file based database or into an array.

What are your ideas?
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: How to route requests in web applications?

Post by alex.barylski »

Why not use an existing framework like Zend and read their docs on routing?

It's a confusing subject when first getting started but once the idea is clear it's easy as anything to properly route your requests.
Post Reply