URL router that loads dependent objects How can I write my code more efficient (not repeating same code)?

And is there a solution that simplifies the way of having to create a lot of dependency objects over and over again whenever I instantiate a new class (as seen in the load method)?

Any suggestions are welcome.

class Router
{
    private $request;
    private $cleanUri;
    # control attributes
    private $controller;
    private $action;
    private $params = [];

    public function __construct(Request $request)
    {
        $this-&gt;request  = $request;
        $this-&gt;cleanUri = preg_replace(['#/+#', '(\.\./)'], '/', trim($request-&gt;getUri(), '/')); 

        $this-&gt;parseUri();
        $this-&gt;load();
    }

    private function parseUri()
    {
        $parts            = explode('/', $this-&gt;cleanUri);
        $this-&gt;controller = ($this-&gt;cleanUri !== '' ? ucfirst(array_shift($parts))  : 'Index') . 'Controller';
        $this-&gt;action     = array_shift($parts);
        $this-&gt;params     = !empty($parts) ? $parts : null;
    }

    private function load()
    {
        if (class_exists($this-&gt;controller)) {
            if (empty($this-&gt;action)) {
                $this-&gt;action = 'index';
            } elseif ($this-&gt;action !== 'index' &amp;&amp; method_exists($this-&gt;controller, $this-&gt;action)) {
                //$action value stays the same
            } else {
                if (class_exists('_404Controller')) {
                    $controller = new _404Controller();

                    $controller-&gt;index();
                } else {
                    throw new Exception('404 controller not found. Page doesn\'t exist for: ' . $this-&gt;request-&gt;getUri());
                }
            }

            $controller = $this-&gt;controller;

            //create dependencies
            $db   = new Database();
            $user = new User($db, $this-&gt;request);
            $menu = new MenuHelper($this-&gt;request, $user);

            $controller = new $controller($this-&gt;request, $user, $menu);
            $action     = $this-&gt;action;

            $controller-&gt;$action();
        } else {
            if (class_exists('_404Controller')) {
                $controller = new _404Controller();

                $controller-&gt;index();
            } else {
                throw new Exception('404 controller not found. Page doesn\'t exist for: ' . $this-&gt;request-&gt;getUri());
            }
        }
    }
}
If this unit of code is a router, then it should remain a router. Have the controller handle its dependencies. You could have multiple controllers, each with its own dependencies. You wouldn't want a single router code become a monster just to keep up with the controllers.

class Router{

  private $request;
  private $cleanUri;

  private $controller;
  private $action;
  private $params = [];

  public function __construct(Request $request){
      $this-&gt;request  = $request;
      $this-&gt;cleanUri = $this-&gt;sanitizeUri($request-&gt;getUri())
      $this-&gt;parseUri();
      $this-&gt;load();
  }

  // Extract sanitize. You might want to add more than just this and the constructor
  // is a bad place to put it.
  private function sanitizeUri($uri){
    return preg_replace(['#/+#', '(\.\./)'], '/', trim($uri, '/'));
  }

  private function parseUri(){
      $parts            = explode('/', $this-&gt;cleanUri);
      $this-&gt;controller = ($this-&gt;cleanUri !== '' ? ucfirst(array_shift($parts))  : 'Index') . 'Controller';
      $this-&gt;action     = array_shift($parts);
      $this-&gt;params     = !empty($parts) ? $parts : null;
  }

  // Extract the 404
  private function send404(){
    if (class_exists('_404Controller')) {
      $controller = new _404Controller();
      $controller-&gt;index();
    } else {
      throw new Exception('404 controller not found. Page doesn\'t exist for: ' . $this-&gt;request-&gt;getUri());
    }
  }

  private function load(){

    // If action is empty, use index
    if (empty($this-&gt;action)) $this-&gt;action = 'index';

    // If either controller or method doesn't exist, 404
    if(!(class_exists($this-&gt;controller)  &amp;&amp; method_exists($this-&gt;controller, $this-&gt;action))) 
      $this-&gt;send404();

    // else execute
    $controller-&gt;$action($this-&gt;params);

  }
}


Then the controller could have:

class MyController extends Controller{

  public function __construct(){
    $this-&gt;load(array(
      'database',
      'cats',
      'unicorns'
    ));
  }

  public function index(){
    $this-&gt;database-&gt;getSomething();
  }
}