Are global variables in PHP considered bad practice? If so, why? [duplicate] - php

This question already has answers here:
Stop using `global` in PHP
(6 answers)
Closed 4 months ago.
function foo () {
global $var;
// rest of code
}
In my small PHP projects I usually go the procedural way. I generally have a variable that contains the system configuration, and when I nead to access this variable in a function, I do global $var;.
Is this bad practice?

When people talk about global variables in other languages it means something different to what it does in PHP. That's because variables aren't really global in PHP. The scope of a typical PHP program is one HTTP request. Session variables actually have a wider scope than PHP "global" variables because they typically encompass many HTTP requests.
Often (always?) you can call member functions in methods like preg_replace_callback() like this:
preg_replace_callback('!pattern!', array($obj, 'method'), $str);
See callbacks for more.
The point is that objects have been bolted onto PHP and in some ways lead to some awkwardness.
Don't concern yourself overly with applying standards or constructs from different languages to PHP. Another common pitfall is trying to turn PHP into a pure OOP language by sticking object models on top of everything.
Like anything else, use "global" variables, procedural code, a particular framework and OOP because it makes sense, solves a problem, reduces the amount of code you need to write or makes it more maintainable and easier to understand, not because you think you should.

Global variables if not used carefully can make problems harder to find. Let's say you request a php script and you get a warning saying you're trying to access an index of an array that does not exist in some function.
If the array you're trying to access is local to the function, you check the function to see if you have made a mistake there. It might be a problem with an input to the function so you check the places where the function is called.
But if that array is global, you need to check all the places where you use that global variable, and not only that, you have to figure out in what order those references to the global variable are accessed.
If you have a global variable in a piece of code it makes it difficult to isolate the functionality of that code. Why would you want to isolate functionality? So you can test it and reuse it elsewhere. If you have some code you don't need to test and won't need to reuse then using global variables is fine.

I agree with the accepted answer. I would add two things:
Use a prefix so you can immediately identify it as global (e.g. $g_)
Declare them in one spot, don't go sprinkling them all around the code.

Who can argue against experience, college degrees, and software engineering? Not me. I would only say that in developing object-oriented single page PHP applications, I have more fun when I know I can build the entire thing from scratch without worrying about namespace collisions. Building from scratch is something many people do not do anymore. They have a job, a deadline, a bonus, or a reputation to care about. These types tend to use so much pre-built code with high stakes, that they cannot risk using global variables at all.
It may be bad to use global variables, even if they are only used in the global area of a program, but let's not forget about those who just want to have fun and make something work.
If that means using a few variables (< 10) in the global namespace, that only get used in the global area of a program, so be it. Yes, yes, MVC, dependency injection, external code, blah, blah, blah, blah. But, if you have contained 99.99% of your code into namespaces and classes, and external code is sandboxed, the world will not end (I repeat, the world will not end) if you use a global variable.
Generally, I would not say using global variables is bad practice. I would say that using global variables (flags and such) outside of the global area of a program is asking for trouble and (in the long run) ill-advised because you can lose track of their states rather easily. Also, I would say that the more you learn, the less reliant you will be on global variables because you will have experienced the "joy" of tracking down bugs associated with their use. This alone will incentivize you to find another way to solve the same problem. Coincidentally, this tends to push PHP people in the direction of learning how to use namespaces and classes (static members, etc ...).
The field of computer science is vast. If we scare everyone away from doing something because we label it bad, then they lose out on the fun of truly understanding the reasoning behind the label.
Use global variables if you must, but then see if you can solve the problem without them. Collisions, testing, and debugging mean more when you understand intimately the true nature of the problem, not just a description of the problem.

Reposted from the ended SO Documentation Beta
We can illustrate this problem with the following pseudo-code
function foo() {
global $bob;
$bob->doSomething();
}
Your first question here is an obvious one
Where did $bob come from?
Are you confused? Good. You've just learned why globals are confusing and considered a bad practice. If this were a real program, your next bit of fun is to go track down all instances of $bob and hope you find the right one (this gets worse if $bob is used everywhere). Worse, if someone else goes and defines $bob (or you forgot and reused that variable) your code can break (in the above code example, having the wrong object, or no object at all, would cause a fatal error). Since virtually all PHP programs make use of code like include('file.php'); your job maintaining code like this becomes exponentially harder the more files you add.
How do we avoid Globals?
The best way to avoid globals is a philosophy called Dependency Injection. This is where we pass the tools we need into the function or class.
function foo(\Bar $bob) {
$bob->doSomething();
}
This is much easier to understand and maintain. There's no guessing where $bob was set up because the caller is responsible for knowing that (it's passing us what we need to know). Better still, we can use type declarations to restrict what's being passed. So we know that $bob is either an instance of the Bar class, or an instance of a child of Bar, meaning we know we can use the methods of that class. Combined with a standard autoloader (available since PHP 5.3), we can now go track down where Bar is defined. PHP 7.0 or later includes expanded type declarations, where you can also use scalar types (like int or string).

As:
global $my_global;
$my_global = 'Transport me between functions';
Equals $GLOBALS['my_global']
is bad practice (Like Wordpress $pagenow)... hmmm
Concider this:
$my-global = 'Transport me between functions';
is PHP error But:
$GLOBALS['my-global'] = 'Transport me between functions';
is NOT error, hypens will not clash with "common" user declared variables, like $pagenow. And Using UPPERCASE indicates a superglobal in use, easy to spot in code, or track with find in files
I use hyphens, if Im lazy to build classes of everything for a single solution, like:
$GLOBALS['PREFIX-MY-GLOBAL'] = 'Transport me ... ';
But In cases of a more wider use, I use ONE globals as array:
$GLOBALS['PREFIX-MY-GLOBAL']['context-something'] = 'Transport me ... ';
$GLOBALS['PREFIX-MY-GLOBAL']['context-something-else']['numbers'][] = 'Transport me ... ';
The latter is for me, good practice on "cola light" objectives or use, instead of clutter with singleton classes each time to "cache" some data. Please make a comment if Im wrong or missing something stupid here...

Related

When initiating a PHP class is there any benefit to passing reserved variables through the constructor?

I understand any user input needs to be sanitized.
Any framework I've made does this. Naturally any "applicable" variables/names in any URL query or form input are pre-allocated specifically.
Simple albeit foolish question. Is there any reason you should have a class with a constructor like the following
function __construct( $get, $post, $server )
and initiated as
new TheClass( $_GET, $_POST, $_SERVER );
as opposed to simply grabbing them in the constructor itself as they are defined? Pardon if it's obvious I was pretty good at all this just a bit rusty now. Seeing what you guys think.
One good idea in programming is to think of functions as units that only depend on inputs and only affect on outputs (and maybe the object they're called on). This is also one of the main principles of functional programming.
The most basic tenet of functional programming is that, as much as possible, computation should be pure, in the sense that the only effect of execution should be to produce a result: it should be free from side effects such as I/O, assignments to mutable variables, redirecting pointers, etc. For example, whereas an imperative sorting function might take a list of numbers and rearrange its pointers to put the list in order, a pure sorting function would take the original list and return a new list containing the same numbers in sorted order.
From Software Foundations book.
Reading and writing global variables in different parts and units would make the code buggy, hard to read/understand, hard to follow, etc. It would be a good practice to work with them in only one part of code, and not any functions, methods, etc. From this point of view this is really good to not read $_GET, $_POST, etc. inside __construct or any other methods directly and pass them from somewhere known for the programmer and people who are working on the project. This gets more critic when it's about writing, i.e., in $_SESSION variable. Imagine the $_SESSION value contains some unwanted data and you need to figure out which part of the code is responsible for the issue. If there are many part of the code that change the $_SESSION variable, the debug processes is gonna be very hard.
So in my opinion This is very good to not use global variables as possible.

Why is it bad to use global in all PHP functions? [duplicate]

I'm trying to find out why the use of global is considered to be bad practice in python (and in programming in general). Can somebody explain? Links with more info would also be appreciated.
This has nothing to do with Python; global variables are bad in any programming language.
However, global constants are not conceptually the same as global variables; global constants are perfectly harmless. In Python the distinction between the two is purely by convention: CONSTANTS_ARE_CAPITALIZED and globals_are_not.
The reason global variables are bad is that they enable functions to have hidden (non-obvious, surprising, hard to detect, hard to diagnose) side effects, leading to an increase in complexity, potentially leading to Spaghetti code.
However, sane use of global state is acceptable (as is local state and mutability) even in functional programming, either for algorithm optimization, reduced complexity, caching and memoization, or the practicality of porting structures originating in a predominantly imperative codebase.
All in all, your question can be answered in many ways, so your best bet is to just google "why are global variables bad". Some examples:
Global Variables Are Bad - Wiki Wiki Web
Why is Global State so Evil? - Software Engineering Stack Exchange
Are global variables bad?
If you want to go deeper and find out why side effects are all about, and many other enlightening things, you should learn Functional Programming:
Side effect (computer science) - Wikipedia
Why are side-effects considered evil in functional programming? - Software Engineering Stack Exchange
Functional programming - Wikipedia
Yes, in theory, globals (and "state" in general) are evil. In practice, if you look into your python's packages directory you'll find that most modules there start with a bunch of global declarations. Obviously, people have no problem with them.
Specifically to python, globals' visibility is limited to a module, therefore there are no "true" globals that affect the whole program - that makes them a way less harmful. Another point: there are no const, so when you need a constant you have to use a global.
In my practice, if I happen to modify a global in a function, I always declare it with global, even if there technically no need for that, as in:
cache = {}
def foo(args):
global cache
cache[args] = ...
This makes globals' manipulations easier to track down.
A personal opinion on the topic is that having global variables being used in a function logic means that some other code can alter the logic and the expected output of that function which will make debugging very hard (especially in big projects) and will make testing harder as well.
Furthermore, if you consider other people reading your code (open-source community, colleagues etc) they will have a hard time trying to understand where the global variable is being set, where has been changed and what to expect from this global variable as opposed to an isolated function that its functionality can be determined by reading the function definition itself.
(Probably) Violating Pure Function definition
I believe that a clean and (nearly) bug-free code should have functions that are as pure as possible (see pure functions). A pure function is the one that has the following conditions:
The function always evaluates the same result value given the same argument value(s). The function result value cannot depend on any hidden information or state that may change while program execution proceeds or between different executions of the program, nor can it depend on any external input from I/O devices (usually—see below).
Evaluation of the result does not cause any semantically observable side effect or output, such as mutation of mutable objects or output to I/O devices.
Having global variables is violating at least one of the above if not both as an external code can probably cause unexpected results.
Another clear definition of pure functions: "Pure function is a function that takes all of its inputs as explicit arguments and produces all of its outputs as explicit results." [1]. Having global variables violates the idea of pure functions since an input and maybe one of the outputs (the global variable) is not explicitly being given or returned.
(Probably) Violating Unit testing F.I.R.S.T principle
Further on that, if you consider unit-testing and the F.I.R.S.T principle (Fast tests, Independent tests, Repeatable, Self-Validating and Timely) will probably violate the Independent tests principle (which means that tests don't depend on each other).
Having a global variable (not always) but in most of the cases (at least of what I have seen so far) is to prepare and pass results to other functions. This violates this principle as well. If the global variable has been used in that way (i.e the global variable used in function X has to be set in a function Y first) it means that to unit test function X you have to run test/run function Y first.
Globals as constants
On the other hand and as other people have already mentioned, if the global variable is used as a "constant" variable can be slightly better since the language does not support constants. However, I always prefer working with classes and having the "constants" as a class member and not use a global variable at all. If you have a code that two different classes require to share a global variable then you probably need to refactor your solution and make your classes independent.
I don't believe that globals shouldn't be used. But if they are used the authors should consider some principles (the ones mentioned above perhaps and other software engineering principles and good practices) for a cleaner and nearly bug-free code.
They are essential, the screen being a good example. However, in a multithreaded environment or with many developers involved, in practice often the question arises: who did (erraneously) set or clear it? Depending on the architecture, analysis can be costly and be required often. While reading the global var can be ok, writing to it must be controlled, for example by a single thread or threadsafe class. Hence, global vars arise the fear of high development costs possible by the consequences for which themselves are considered evil. Therefore in general, it's good practice to keep the number of global vars low.

Are PHP global constants a good modern development practice?

I'm working on a new project with a sizeable PHP codebase. The application uses quite a few PHP constants ( define('FOO', 'bar') ), particularly for things like database connection parameters. These constants are all defined in a single configuration file that is require_once()'d directly by basically every class in the application.
A few years ago this would have made perfect sense, but since then I've gotten the Unit Testing bug and this tight coupling between classes is really bothering me. These constants smell like global variables, and they're referenced directly throughout the application code.
Is this still a good idea? Would it be reasonable to copy these values into an object and use this object (i.e. a Bean - there, I said it) to convey them via dependency injection to the the classes that interact with the database? Am I defeating any of the benefits of PHP constants (say speed or something) by doing this?
Another approach I'm considering would be be to create a separate configuration PHP script for testing. I'll still need to figure a way to get the classes under test to use the sandbox configuration script instead of the global configuration script. This still feels brittle, but it might require less outright modification to the entire application.
In my opinion, constants should be used only in two circumstances:
Actual constant values (i.e. things that will never change, SECONDS_PER_HOUR).
OS-dependent values, as long as the constant can be used transparently by the application, in every situation possible.
Even then, I'd reconsider whether class constants would be more appropriate so as not to pollute the constants space.
In your situation, I'd say constants are not a good solution because you will want to provide alternative values depending on where they're used.
These constants smell like global variables, and they're referenced directly […]. Would it be reasonable to copy these values into an object and […] convey them via dependency injection?
Absolutely! I would go even further and say even class constants should be avoided. Because they are public, they expose internals and they are API, so you cannot change them easily without risking breaking existing applications due to the tight coupling. A configuration object makes much more sense (just dont make it a Singleton).
Also see:
Brittle Global State & Singletons from
http://misko.hevery.com/code-reviewers-guide/
To answer this question it is important to discuss the style of code being written.
PHP 5 includes a number of useful OOP features, one of which is class constants. If you're using an object oriented approach, rather than polluting the global namespace, or worry about overriding common constants, you should use class constants.
FOO_BAR could be FOO::BAR in the end, it comes down to the scope of where you want the constant defined.
If you're writing a more procedural style program, or mixing procedural with some classes, global constants aren't an issue. If the code you're working on is becoming unmanageable due to the constants you're using, try changing things around. Otherwise, don't worry about it.
Additionally, class constants wont allow you to use function return values, global constants will. This is great when you have a value that wont ever be changed throughout the scope of the program, but needs to be generated.
using constants for database connection information is perfectly fine. This prevents hard-coding it within the object itself and since its read-only you can't overwrite the values.
I'm not fond of hard-coding my settings in an object, as things can change, but if you wanted to do that, that would work just as well.
If You have PHP 5.3 or newer, You may use namespace.
http://www.php.net/manual/en/language.namespaces.php
It works with const variable = 'something';
Unfortunately, it doesn't wokrk with define('variable','something');
Globals in namespace are encapsulated. In some situations it is better than having an object.
I don't agree constants, nor the hardcode :-)
I prefer, performance aside, Zend_Config_Ini from ZendFramework.
You can overload sections, maintain the values read-only in memory, and others:
http://framework.zend.com/manual/en/zend.config.adapters.ini.html

functions.php vs OOP [duplicate]

This question already has answers here:
Classes. What's the point?
(12 answers)
Closed 9 years ago.
if i have a collection of useful functions in a file called functions.php (easy enough)
what would be the advantage of OOP?
I want to learn it, but its pretty in depth so before I dive it, would be nice to know if there is an advantage. I can send variables to the functions just as easily as I can receive them.
example i have
functions del_some_string($x,$y)// made up function to delete y number of letters from $x
why would this be better as a OOP?
Depends on what the functions do, if you have some common data on which you do various operations to manipulate the same data you might want to model it in a class. On the other hand if all data you are working with has no relation with each other there is not really a benefit of using OOP.
For example the function you mentioned is more a utility function than a member of a class.
I've been using PHP for roughly 10 years now. I can't count how many times I've run across "functions.php" or "library.inc.php" or one of its many equivalents.
It's a bad idea. Don't do it. If you find yourselfs writing files like that, stop it. NOW.
It's not a matter of OOP vs functional programming. It's a matter of organising your code. Group your functions and variables properly and OOP will feel natural. If your functions do many things and don't lend themselves easily to being grouped, try to refactor them so they only do ONE thing at a time. You'll find that this also lets you strip a lot of redudancy out of your existing functions.
You can use OOP to encapsulate your code further: put your variables into objects and have the functions that operate on these variables either be property methods of those objects or interact with these objects as input. Avoid "global" and don't modify your function arguments routinely.
Your problems aren't the problems you think you have.
EDIT: As for your example: since strings aren't objects in PHP, you can't really put that function in a sensible class, so you'd probably want to put it into a utility module with other string functions and use it as you already do. Still, tearing apart your functions.php and turning it into a collection of atomic modules does wonders to your code's readability. You may find a file containing assorted functions readable because you are familiar with its contents, but another coder (and "you after three months of not using the code" IS another coder) will not.
EDIT2: Please understand that "OOP" doesn't magically make everything better. It's a tool that is supposed to help you writing better code. If you use OOP everywhere, you're probably doing it wrong (or writing for Java *cough*). If you use OOP without understanding things like structured code first, you won't get anything out of it, either.
It wouldn't. It's not a matter of better or worse. It's the paradigm that's important.
All computer programs aim to solve a problem. You can use Imperative Programming or you can use OOP (among others) to solve this problem. OOP will just change how you structure and organize your application, because it embraces concepts like encapsulation, polymorphism, and inheritance (to name some). These are not generally available in imperative programming, but that doesn't mean imperative is worse. It's just different.
If you are coding PHP, you can use either or. PHP is not a strictly object-oriented language. However, as of PHP5, there is an increased focus on OOP. New additions to the API are almost always Classes now (SPL, DateTime, Internationalization). If you want to use those, you definitely should look into OOP.
OOP goes much further then just calling functions.
Classes collect functions that operate on the same set of data or share the same goal. But another advantages of classes taking DRY to the next level. With functions, you can encapsulate some simple task so you don't have to repeat that over and over. With OOP, you can encapsulate more complex tasks so you won't have to repeat that.
If you tend to pass the same sort of data to several functions sequentially, you can think about using a class, and pass that data to the constructor and saving it in the class. That way, you can call the functions without having to pass that data each time.
You can instance of a PHP class and use it's all combined properties and methods. You can manipulate an object during the execution of the script, and state is saved.
class Myclass{
public $a, $b, $c;
public setA(){
$this->a = b;
}
public getA(){
return $this->a;
}
}
this is what you cant do with a function:
$x = new Myclass;
$x->setA();
print $this->getA();
you can't simulate the same functionality with a functions PHP. You run your functions one time, and since there is no instance, you have to hold these variables somewhere else. If you write a big aplication, this functions.php will be a big black hole. If you use seperated classes with it's functionality-aimed properties and methods, you can extend your PHP application as much as you want. If you don't use OOP, you can never setup a framework. but you will understand the importance of OOP, when you have to write something huge.

How Bad Are Singletons?

So ....
There are obviously many questions that all have been asked about Singletons, Global State Variables, and all that great stuff. My question is,
If Singletons and Globals are So Bad, Why are they used so often?
The following examples are simply ones off the top of my head that I believe are used by a good chunk of people.
I give you a function from CodeIgniter that uses a psuedo-singleton function:
(system\codeigniter\Common.php Line 89)
/**
* Class registry
*
* This function acts as a singleton. If the requested class does not
* exist it is instantiated and set to a static variable. If it has
* previously been instantiated the variable is returned.
*
* ......
*/
function &load_class($class, $instantiate = TRUE)
{
static $objects = array();
// Does the class exist? If so, we're done...
if (isset($objects[$class]))
{
return $objects[$class];
}
.......
}
By placing every object into a single registry, you can't use their load_class function to create multiple instances of anything. This is especially inconvenient when you want to use classes as data structures.
Also, because there is only one instance of all those classes, it leads into the argument against Global State. Which leads me to .....
The entire Wordpress System, which runs mainly on global variables. All of the data for looping through posts is strewn about in various globals.
(wp-includes\query.php Line 2644)
/**
* Setup global post data.
*
*....
*/
function setup_postdata($post) {
global $id, $authordata, $day, $currentmonth, $page, $pages, $multipage, $more, $numpages;
$id = (int) $post->ID;
$authordata = get_userdata($post->post_author);
....
}
These are just two main examples of Frameworks that use Singleton/Globals as the basis for their entire system!
So .. is it just because these systems haven't caught up to OOP methodology? It just doesn't make sense when you have so many people telling you not to use Global Variables or Singletons, to make your entire system based on said practices.
There of course is the argument about backwards-compatibility with PHP4. I still think that there were ways to do OOP programming in PHP4, as classes were still available.
Because it's relatively easy to work with singletons, and working without takes much more detailed planning of your application's structure. I asked a question about alternatives some time ago, and got interesting answers.
People discourage the use of global variables because it increases the likeliness of bugs. It's so much easier to make a mistake somewhere if every function in your program accesses the same global variables, and it's much harder to debug. It's also much harder to test for.
I imagine they're still used so often because programmers are lazy. We don't want to spend time up-front making the code all organized and pretty, we just want to get the job done. It's so much easier to just write a global function/variable/whatever than to modularize it, and once you've started down that path it's too much of a pain to go back and refactor. Maybe that's the reason: They started out that way and simply never turned back.
Probably because of the Design Patterns book by the GoF. It's become too pervasive and people treat it as infallible.
Reasons in PHP4-based apps like WP or CI are partially due to PHP4's worse support of OOP constructs.
Globals and singletons are also simple: It requires much less thinking to slap something in a global than building it with proper OOP practices. It's simpler to access them too, just point the code at the name and that's it instead of needing to pass the object in from somewhere else.
One negative side effect of global state (global variables, singletons, etc.) is that it makes things much more difficult to unit test.
ps: In my experience wordpress in general has a pretty poor quality of code. I would not use it as a metric of anything...
If Singletons and Globals are So Bad,
Why are they used so often?
I think the gist of it is that Singletons make things easy. At least at first sight. I don't have enough experience with the matter to say anything more useful, however I found the following a good read:
Singleton Considered Stupid (Steve Yegge)
Global variables and singletons are popular because they are simple and convenient.
Dependency injection, the only reasonably convenient replacement for global things, is still rather unknown in the PHP-community.
The PHP-community often prefers simple hacks over proper solutions.
Many PHP-developers are quite clueless about programming and know barely enough to make their programs work.
In the process of cleaning a Singleton would represent hiding the dirt in the dark corner instead of cleaning.
It's so widely used because it does it's job of hiding problems very well.
It's a good thing for those who are to clean, but don't want to.
It's a bad thing for those who are up to actually clean something.
Consider Dependency Injection http://martinfowler.com/articles/injection.html
if a Singleton is causing a problem you can't hide anymore.

Categories