4

I'm building my own MVC framework (to improve my PHP) but I don't know how to deal with good practices.

In my Router I have a method to create a link by using a route-name and the parameters (the method returns the well formatted url), so in my controllers I can use something like:

//inside an action of any of my controllers
$router = Router::getInstance(); //the router is a Singleton
$url = $router->createUrl('articleReadOne', array(65, 'matrix')); //$url = "article/read/65-matrix"
$this->redirectTo($url);

Or inside my views:

//inside a view
<?php $router = Router::getInstance(); ?> 
<a href="<?php echo $router->createUrl('article-read', array(65, 'matrix')); ?>"> Click me </a>

But I can read all over the net that using Singleton is a bad practice (even for a Database class).

I really need to have access to my createUrl() method from inside my controller and from inside my Views, but if I don't use a Singleton Router class, how can I "inject" my Router to my Controllers and be able to use it? Is it really bad to use Singleton in a case like this?

Thank you for your help.

3
  • what kind of routing do you have in front of the controllers? A front end controller where all requests are redirected to index and routed manually from there, or some other scheme? Commented Oct 11, 2015 at 15:40
  • Hello, all the requests are redirected to index.php, than I look into my route-collection if the URL match one of my route. If that's the case, I call the appropriate controller and the appropriate action. Commented Oct 11, 2015 at 15:53
  • 1
    then you could just inject the router in that action call.. $controller->listAction($router, $otherStuff) or similar Commented Oct 11, 2015 at 16:42

1 Answer 1

2

A couple things:

Generally your router comes before your controllers. All it should be concerned with is looking at the URL/Request, and sending the info to the right controller. Once you're in your controller, you shouldn't need to refer back to the router for any reason. This means if you need access to your createUrl() method from inside your controllers or from inside your views, you'll need to move it somewhere else.

Usually your controllers have access to your views, but not the other way around. As such you could either add it to a view (maybe a master view from which others extend), or to a controller (again, master controller from which others extend) from which you call it, and pass the result along into the view as an argument when you instantiate the view.

As for when you hear injecting, all it means is passing something through as an argument, the same way you normally do with function calls. The general advice about avoiding singletons makes sense, as singletons point to the use of globals, which are generally frowned upon. Instead, you should pass the instance of your DB model in as an argument to any classes that will need to use it. Something like:

class User {

    private $dbh;

    __construct($dbh) {
        $this->dbh = $dbh;
    }

}

$user = new User($dbh);

In this way, you'll have access to the database handler without opening it up globally and giving everything TOO much access to it.

Hope this helped. Your research is leading you right so far, so stick with it!

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your anwser and your tips! It helped me well!
@carbide20 Hello. For 300 points, would you take a stab at my question on Routing classes in PHP? stackoverflow.com/questions/42172228/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.