adam_bray Posted June 8, 2014 Share Posted June 8, 2014 I'm looking for some clarification here from different viewpoints to understand real world applications.In a previous thread, I suggested to someone that they read up on singleton methods to restrict class duplication (oops!), I was quickly (and rightfully) shot down. I did this after having read through blog posts that also suggested singleton design to stop multiple MySQL connections. At the time I didn't consider that could be useful to some people.. fair enough.Thankfully I don't use singleton methods within my own code, but I do use static methods for most things. Reading through numerous blog posts, tutorials, etc.., it seems like static methods can also be considered anti-design and is something to avoid.So now it seems I'm at a point where I need to rewrite my existing framework & CMS, probably using dependency injection within my classes. I understand how this works, and why it makes sense.What I'm struggling with is understanding how to use dependency injection within a (personal) CMS application.For example - I have a config.ini file I have a class that reads the .ini file, stores the variables, and provides me methods to access them I have a content class that selects the relevant page/component from the DB (db & config dependency), then displays it via my template engine. Within the included view files I call component classes (articles, contact, etc..), each of these require a connection to the DB, which has a config dependency. Here's some code to explain it better -index.php <?php $settings = '/config/config.ini'; $config = new Config($settings); $db = new Database($config); $content = new Content( $db ); // Config may also be passed for content config - keeping it simple for example print $content->loadPage($_GET['page']); // This would now include the code below ?> Let's say that this then loads the article index (through $content->loadPage()). The view would look something like this -article_index.php <?php // Duplicated code $settings = '/config/config.ini'; $config = new Config($settings); $db = new Database($config); // Article code $articles = new Articles_Model($db); return $articles->getArticles(0,15); ?> Now my problem is that I'm duplicating the config and db class calls for no reason.Is the sollution to store these within a registry class? But then I'm creating globals, which again seems anti-design. Or is the problem how I load the active page?Any insights would be much appreciated. Quote Link to comment Share on other sites More sharing options...
requinix Posted June 9, 2014 Share Posted June 9, 2014 (edited) "Anti-design" does not mean something is bad. It means it's easy to abuse the design towards a bad end. Registries, singletons, static members, being anti-design means that you should think about how you are using them, not that you have to avoid them entirely. I could go for any of: a) A registry of the values, as you do need to propagate values across multiple locations b) A singleton for the various objects, but only if there are never multiple configuration files, configuration objects, or database connections c) Dependency injection by way of variables: have loadPage() set values, maybe looking like print $content->loadPage($_GET['page'], array('db' => $db));and then you'll have $db (or $this->db or whatever) set for you. This actually shares a lot in common with (a). Edited June 9, 2014 by requinix Quote Link to comment Share on other sites More sharing options...
ignace Posted June 9, 2014 Share Posted June 9, 2014 (edited) None of your examples includes a DI. Here's a rewrite of your index.php with DI: $di = include 'includes/di.php'; $di['content']->loadPage($_GET['page']);And your article_index.php $di = include 'includes/di.php'; $di['articles']->getArticles(0, 15);The includes/di.php could look something like: // download from http://pimple.sensiolabs.org/ $container = new Pimple(); $container['config_filepath'] = 'config/config.ini'; $container['config'] = function($c) { return new Config($c['config_filepath']); }; $container['db'] = function($c) { return new Database($c['config']); }; $container['content'] = function($c) { return new Content($c['db']); }; $container['articles'] = function($c) { return new Articles_Model($c['db']); }; return $container;For all your autoloading you may want to consider composer Edited June 9, 2014 by ignace Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.