Jump to content

Recommended Posts

I have read in several places on the internet that the global variable command, such as this:

 

function myFunction($var)
{
    global $external;
}

 

will be removed as of PHP 6. Is this actually true? I've used this in quite a few places in order to access language specific string arrays instead of passing the value to the function. Is this bad practice?

Link to comment
https://forums.phpfreaks.com/topic/169647-will-global-not-be-available-in-php-6/
Share on other sites

I think they meant register globals.  Which is when a variable is automatically registered for the keys in $_REQUEST

for example

 

website.php?blah=whatever

with out doing anything you would have a variable available

$blah 

 

same thing for posted data.  GIANT security hole.

yes, they are referring to register globals being removed.  But FYI what you are doing is also bad coding practice.

 

Would it be better to pass the string?

 

No, this is a VERY good sign that you need to use OOP (Object Oriented Programming) or classes for your development process.

 

Edit: typo

Globals aren't automatically bad.  You can write perfectly valid, excellent performance, easily maintainable code with globals.  5.3 introduces also introduces namespaces, so you don't have to worry about global variable name conflicts with other libraries.

 

It's like the addition of goto.  You don't have to take something away from a language because the potential of abuse, you just have to have some faith that developers won't be idiots about it.

You're missing the point about globals.  The problem with using them inside functions is that they transcend the scope of the function.  The problem with this is that now you cannot 100% guarantee that the function is going to do exactly what it's supposed to do every time, because there is now something outside of the scope of that function being used inside it.  The whole point of functions and even classes is to abstract certain things out of everyday programming.  Well in order to do that, you have to be confident that those abstracted pieces of code are doing what they are meant to do 100% of the time.  When you do not respect scope, you can no longer be 100% certain that issues are not within those abstracted pieces.

For example, if what you were passing into the function using the global keyword was a database connection, you have now made your code specific to that one single database connection. If you want to use more than one database connection, you must now use more code to shuffle around and keep track of database connections or even worse copy, EDIT, then retest your function code (which defeats one of the purposes of using functions, you write and test a function ONCE, then reuse it with confidence that it will work without needing to modify and test it again just because you changed how it is being used in the calling code.)

I'm not missing any point.  What's the difference between making your code break because you misused a class property and making it break because you misused a namespaced global?  You can run into the same problems with either method.  Saying that one is automatically better than another is just short sighted.

They both break encapsulation, which is bad. The difference is that a global variable for sure breaks encapsulation no matter what, while a class property can be marked as private or protected. Even so, the global variable is still available throughout the entire script while the object is only available in the local scope.

I'm not missing any point.  What's the difference between making your code break because you misused a class property and making it break because you misused a namespaced global?  You can run into the same problems with either method.  Saying that one is automatically better than another is just short sighted.

 

 

(This isn't technically in response to the a vs b argument but more of why both are bad.)

 

Ok, what if you make an application and name your db connection resource $db and use global to pull it into every function.

 

 

Now, let's say another developer comes along later (or you after a while) and makes a variable named $db in the global scope that has a different value.  Suddenly the rest of your application doesn't work.

 

 

 

Globals are all fine and good until something changes, and change can always happen, so globals are best to be avoided.

Now, let's say another developer comes along later (or you after a while) and makes a variable named $db in the global scope that has a different value.  Suddenly the rest of your application doesn't work.

 

This is exactly why PHP 5.3 introduces namespaces, which is a feature other languages have had for years.

 

I'm not trying to say go use globals all you want or anything.  But there are times where it makes sense.

 

Take a typical global $db connection object, and wrap it up in a namespace.  Say that database connection is an oci8 library using FAN.  The object will internally manage connectivity faster and better than any connection library you could create in PHP. 

 

Is there any advantage you would get with the bulk and overhead wrapping this inside another object or creating a singleton for this object?  It's just code bloat unless you can say otherwise.

"Take a typical global $db connection object, and wrap it up in a namespace.  Say that database connection is an oci8 library using FAN.  The object will internally manage connectivity faster and better than any connection library you could create in PHP. "

 

doSomething($variable, $db);

 

 

Why not do that instead of a global?  Then you can call doSomething from any scope without having to worry about where in the world $db came from.

 

 

 

"Say that database connection is an oci8 library using FAN.  The object will internally manage connectivity faster and better than any connection library you could create in PHP. 

 

Is there any advantage you would get with the bulk and overhead wrapping this inside another object or creating a singleton for this object?  It's just code bloat unless you can say otherwise."

 

 

Now you're just getting off topic.  I never disagreed over that.  Of course anything written in C will be faster than anything in PHP.  (Well assuming they do the same thing and are of the same quality.)

Have you ever tried working on a project that made heavy use of globals, but you didn't create? It's a pain in the ass trying to figure out where anything comes from and trying to debug it. The only reason why it works for the current developers is because they can remember that. Should they leave it and come back later on, chances are they'll be pulling their hair as well. It's also a problem with interoperability/portability. What if two 3rd party libraries use the same global variable for different purposes?

 

Case in point, when developing the website for PHP Freaks I wanted to use the SMF API for a couple of things. However, in true SMF style it messed with global things, the super globals, the sessions and a lot of other crap that made it completely incompatible with Zend Framework. The SMF API only works if you build your site around it. It doesn't work as a third party library even though it would have been possible if the SMF team didn't churn out a lot of shit code constantly. Also, a couple of times when people had requested some mods for the forum I've taken a look at trying to do it, but it's virtually impossible finding your way around the SMF code base because everything depends on each other and that global object you're using could literally come from anywhere.

 

Regarding the speed thing. If you're looking for maximum performance, why are you writing PHP code in the first place? You should be writing assembly. Raw performance is not everything.

I certainly agree that globals can be and have historically been misused.  The same thing can be said about PHP in general.

 

But the point I'm trying to make is that there is nothing automatically bad about referencing a global variable inside a function.  I gave an example where if it were a small app with a small db connection layer, a global would be perfectly fine.  Yes, there are other ways that would work in such a situation, but they don't necessarily provide any type of inherent advantage.

"Yes, there are other ways that would work in such a situation, but they don't necessarily provide any type of inherent advantage."

 

 

Errr....  Yeah, they do have an inherent advantage.  Not using globals....

 

 

You never know if that small application is ever going to grow.  What's the harm in just passing the variable instead of globalizing (yeah, I just created a word) it?

But that binds the app to be a small app. Eventually you might want another feature, and another, and one more. It's just a small app, so we'll disregard anything even remotely related to good practice. At one point it's one giant pile of spaghetti code with a lot of interdependencies. You could have just passed the variable as an argument instead.

 

Another issue is unit testing. When doing unit testing you test individual components of the application individually. Good luck doing that with code that relies on global objects. You couldn't for instance create a mock database object either.

 

Because you wasn't able to properly unit test your code, and you now have a tightly coupled application, there is a great risk that fixing one bug creates a different bug another place. Because you have no unit tests, you have no means of finding out before it's too late. You'll be spending more time hunting down bugs and fixing them than writing new features. You've experienced what is called "code rot" or "software decay".

 

There is never a good reason why you would use a global variable.

xylex: your argument is akin to saying there is nothing inherently wrong with coding a site as entirely static html.  It is true, there isn't.  But if you want any kind of flexibility, ease of use for expanding/updating, etc.. it is not a good idea to code everything static.  The same principle applies here.  In and of itself making it global is not bad.  But the point is, there's really no good reason to use it, either, because in practice it's better to do it other ways.

Daniel- On the scalability thing, I said a small app, but even if it did grow, going with that oci8 $db connection example, that would scale just fine.  You wouldn't be managing connection pools to an Oracle cluster from inside the app.

 

You also can't unit test a function that relies on a database connection without having a connection to the database in general.  You do the same thing, you're just initializing differently.

 

xylex: your argument is akin to saying there is nothing inherently wrong with coding a site as entirely static html.  It is true, there isn't.  But if you want any kind of flexibility, ease of use for expanding/updating, etc.. it is not a good idea to code everything static.  The same principle applies here.  In and of itself making it global is not bad.  But the point is, there's really no good reason to use it, either, because in practice it's better to do it other ways.

 

That's exactly the point that I'm trying to make, in reverse.  Saying that you should never use globals and PHP would be better off without them would be like saying you should never code static html and Apache would be better off not serving up raw html files and always use an interpreter so people won't make static sites anymore.

You can't unit test a function that relies on a database connection without having a connection to the database in general.  You do the same thing, you're just initializing differently.

 

Yes, you can.

 

http://en.wikipedia.org/wiki/Mock_object

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.