PHP: global variable alternatives?
I'm working on a PHP project, and from time to time between things I read online and things I see in forums, etc. I keep reading that you shouldn't use php globals. Making sure that I don't get that mixed up with开发者_运维问答 PHP register_globals, because I'm not, I have been researching, but I haven't really found why or any type of alternatives.
So, my question is simple. Should I not use the global
keyword in PHP? Additionally, if I shouldn't (or should), are there any alternatives? Reason being is, I have noticed that I need to access a variable defined in another file and I need to reference or call this variable in a function, lots of functions, and I'm kind of getting tired or using the global $var_name;
code so much.
Any ideas (or am I just plain wrong)?
Static classes and singletons are only little better than globals. Static classes merely group global variables, but the variables themselves are still globally reachable, single instance variables. Same goes for Singletons. While they have their uses, they should not be used as a general replacement for globals. PHP makes it tempting though, especially because of having to declare global variables in functions, while static classes are available always and everywhere.
You'd best put the variables in a class (like a 'AppConfig' or more specific class), and create an instance of that class to hold specific values. Then, pass that instance to all methods in your framework. That way, you don't rely on a specific Singleton implementation, and are truly flexible.
But, I must admit that it's a lot of work, especially when you're not experienced yet. So using a singleton now is probably ok, as long as you keep this answer in mind when you feel your singletons itching somewhere in the future.
You're not wrong, you just need to think of some architecture for your application. : )
If you have shared data between classes, you should use a model that contains that shared data and has an API accessible to all your classes to retrieve that variable.
For simplicity's sake, you can use a Singleton to contain any shared data.
The PHP Patterns Page has an example of a Singleton. The idea behind a Singleton is that you always access the same instance (version) of that class, so that if you change the variable there, it will automatically be changed elsewhere.
Globals are only bad if you're writing Object Oriented Code. If you're code is procedural, globals are just fine.
If its using objects, you need to use dependency injection (new Object(new Collaborator)
).
To manage that, you would probably need to use a dependency injection container eventually.
If you start using static classes and singletons, you're actually no longer writing 100% OO code.
But bottom line, if its regular procedural code, there's nothing wrong with globals.
As some other's have said, there is nothing wrong with using globals; especially on a short script it can actually keep your code more readable than obscuring it with too much OO structure.
But you wrote: "I need [this variable in] lots of functions, and I'm kind of getting tired or using the global $var_name; code so much"
This suggests what you actually want is for all those functions using $var_name to be in a class. As a first stage refactor, you'll pass in the variable from the other file to the constructor, and replace all your $var_name
references with $this->var_name
, and then strip out all the global $var_name;
lines.
You may end up with one global instance of this class, but that is okay. Globals aren't evil, but they should be managed and documented carefully as your code gets more complex.
If you don't already have it, Martin Fowler's Refactoring book is a good read to help you cope when your 100-line script is now 1000-lines and getting you down. (Examples are in java, but still accessible for a PHP programmer.)
In general, global variables introduce problem with security and maintainability of code. If you are using modern PHP, then a good solution is to have a static class that can act as a holder for all the globals you need. For example, sfConfig from Symfony Framework is a good example. You can see the docs and code here for inspiration on how to make your own (or just clean up the code to use in your own project... it's fairly standalone).
精彩评论