I understand that global variables should be avoided generally. As a beginner, I'm trying to understand whether making a $view variable global in a dynamic web program built following MVC principles is one of those cases where globals are a good idea.
In my program, I create the $view (as an object that contains an empty array) in index.php, and turn it into a global in the controllers that use it.
Thanks!
JDelage
Making a variable global is not a good idea when you using an MVC patterns in a project. There are other solutions that will make use of your MVC more wisely.
If you should have a single use of a resource, use a singleton pattern. Something like
and get that view object anywhere with
This way, you don't have global variables and you are using best OO practices.
However, as others have pointed out, having a singleton view is not necessarily a good idea... A probably better approach would be to make your dispatcher code create a new view and set it to the controller being called, so the controller would have a view available and access it directly.
The view (not being a singleton) could also be a public property, or accessible though a public method of an application singleton;
My_Application::getInstance()->getView();
that could also hold the current configuration, paths,The name
My_view
suggested is merely an example. Using some sort of naming convention helps organize the code and helps getting rid of all those include/require calls in your script headers. This is not in your question's scope, however for clarity's sake, I'll briefly explain :In your bootstrap, you declare your autoloading function (as defined in the PHP manual) :
And simply include the file
'/path/to/lib/My/Application.php'
and when you will accessMy_View
, theload
function will be called with$name = 'My_View'
and the function will simply require the file'/path/to/lib/My/View.php'
for you. This is not much for one file, but if all classes are namespaces like so, you only need one include (Autoloader
) and everything else is loaded automatically.Why? If you controller needs the
$view
then just pass it in via the constructor or a setter. Dependencies on Globals can always be resolved by using Dependency Injection.Also, please reconsider if the View should be just an array. The View has to be rendered at some point. Rendering is a responsibility I'd see on the View. An array cannot render itself, so I assume you are doing it elsewhere. That would be a violation of the Single Responsibility Principle. I'd rather do something along the lines of (simplified):
Global variables should be avoided, true. They are however useful for holding global state - that doesn' lead to intercoupling - as in specifically a $config array/object.
But in your case, I'm not sure the $view is a good idea. Firstly, I believe what you are assembling is output data. The "view" in MVC is more of a output template, what I believe your index.php is? If so, then you are actually assembling the $model. Uncertain.
It's theoretically cleaner to pass this variable to the controllers explicitely then. If it's however really only that one global variable, and you promise not to overdo it, passing it around as global is ok.
But you could also follow the mentioned singleton pattern. However I'd recommend the procedural variant, because it's cleaner:
This way you could use
$view=view();
to localize it in your controllers, keep using it as array$view["xy"]=
and as object$view->xy=
at the same time.Or just write
print view()->title;
in the template.A solution to this problem I've seen is having controllers extend from a base controller. Within that base controller a
$data
property is instantiated; new view data is then appending to this property. For example:The render method (which could be loaded automatically after a method has ran, rather than being explicitly) would then assemble a template using the data held within the
$data
array.Hope this helps and you're able to implement a working solution.