Global variables are a code smell. This statement is both true and false. What is true is that they are a problem when they are no longer the right variables to be global.
Today I had to re-factor a function to be able to use multiple servers inside one script instance. Initially, the server connection was created and stored in one variable that was then referenced. This worked well, because the code that called this function didn’t have to worry about what server connection was involved.
Of course, the problem started when I added a second server into the mix. Now, this function had to be able to access either server, selected by the code in some of the places that called it. The easiest way to solve this would have been to keep the global and add a second optional parameter to override it, but that would not be as clean a fix as just fixing the global.
And so I re-factored the function call to pass in the server connection to use. This makes the function more flexible, because I can add new servers to the mix and just pass in the variable for the one I want to use. The other benefit is that in eliminating the global, this function is now finally completely self-contained, making it that much easier to test and fix.
Globals can be useful, but will make it harder to properly test a function, and complicates matters if the function that uses them is widely used and has to be changed.
Choose carefully how to use them.