Concerns about global variables

I’m trying to play around to see if I could make my own framework that suits my need. One idea that I’m having is to have several global classes running throughout the script. Such items include, a session variable, a database variable, an error variable etc. It seems that there could be a lot of problems, but i’m not sure so decided to come here to ask. Are there any implications in terms of security, memory usage etc.?

Thanks.

In terms of security, there is nothing global “classes” can do to hurt you.

Memory usage will be zero over the usual, because the instance is only created once.

Check out the Singleton pattern ( http://en.wikipedia.org/wiki/Singleton_pattern ) – it lets you get a class’ only instance from anywhere.

It depends on what your final vision of your application is.

I mean, I personally never store anything (to be later retrieved) in the global namespace other than settings as constants. Anything ‘global’ may only be global to a part of the application, so I find it better to store the superglobal-accessing objects ($_POST, $_GET, etc) and other important large-scope objects (e.g. a Database object) in one object, to then pass to parts of the application (I believe it’s called the Registry pattern).

Sometimes this isn’t needed; whilst many OOP purists will tell you to avoid singleton completely - sometimes making your code more intricate just to allow for un-required potential is just a waste of time and code.

It certainly has benefits. An example is if you want to simulate a request - you could fill a dummy POST object to include data and simulate a form submission to an area of your site. You could also fill parts of a page with the output of several requests - which IS beneficial. It means that you can have a page to get, for example, the output of a shopping cart. That could be grabbed and placed into a page with PHP, but the same request could be fired by Javascript to update a cart ‘live’.

Just try as many styles as you like. Whichever you prefer, benchmark and find which is the more efficient. Sometimes it may surprise you!

Thanks for all the input. I’m right now imagining a scenario where all data needed are carried over by a constantly alive session. Is this going to be fine?

Hi :slight_smile:

Instead of having globals running around, I would pass my “global” objects to the constructor of objects using them. In terms of maintenance, it will save you a lot of troubles.

t.

Hi tetsuo,

I see what you saying there, but one potential issue I see is, it’s harder to manage. As our library expands and more objects start to kick in, and if we want to change the ‘global’ objects, we have to change it in every single class that had them.

But thanks for the idea though, I think it’s something I could potentially work on and improve with.

I think that is an example of "favouring composition … ", which is a good principle to follow.

But still, you end up with “settings” as Jake calls them.

I evolved a means of storing some of these settings ( for the back-end of a multi-user, single-server CMS ) and would like to know what others think of my approach.

projectA_config.php


<?php

    /**
    * testing a static class instead of voodoo-ish includes
    * where values pop up from f knows where
    * 
    * Config file for each client 
    * WSC_ = WebSiteControl 
    **/

class BadMethodException extends Exception {

    function __construct( $msg ){
    $this->message = 'That information-type ' . $msg . ' does not exist in settings' ;
    echo $this->msg ;

    }

}

include 'iwsc_config.php' ;

    /**
    * ProjectA WSC settings, a concrete static class
    * holding admin settings
    **/


class WSC_Config implements IWSC_Config {

    /**
    * static properties - accessors must exist for each 
    * this means 
    * -this class must conform to the interface
    * -the methods are findable
    *
    * -scalar values first
    * =then methods with content
    * -then accessors
    **/


    private static $PROJECT_TITLE   = "Project A";

    final static function getMapLimits(){

    $map_limits['lat']['max']  = 50.1 ;
    $map_limits['lat']['min']   = 51.2 ;
    $map_limits['lng']['max']  = -0.5 ;
    $map_limits['lng']['min']   = -0.6 ;

    return $map_limits ;

    }


    final static function getProjectTitle(){
    
    return self::$PROJECT_TITLE ;

    }

    /**
    * function __callStatic() only works from 5.3 on
    *
    *
    **/

    function __callStatic( $method, $args=0 ){

    throw new BadMethodException( $method ) ;

    }

}  // end class

I just got so fed up of trying to find out where the hell all these globals were coming from that I put them into a static class, and made that static class implement everything in an interface.

That has proved to be very liberating because now I see lines like this:

$map = WSC_Config::getMapLimits();

And at least I know where things are coming from.

I can use reflection to find all my settings.

If I misspell a call (eg getMapsLimit() ) I get a big warning straight away.

If I create a new project and miss out a setting I get a big warning straight away.

It’s verbose, if I decide a new setting is needed, I have to edit the Interface, create the property and an accessor.

I should probably then make this static class available through a registry, if I have understood correctly.

Its the only time I have really used Statics in my code (apart from libraries like PEAR) because Statics never really seemed necessary, but in this case I find it invaluable - but is this a good example of Statics really being put to its good use, a central bag of global “settings”?

That is where the registry comes in. Pass one object around to all you classes and then do things like:
$registry->db
$registry->session
$registry->error

Add as many as you need to the registry and everyone has access.

Hint: when possible, hide that fact that you are using a registry. In your base classes, implement simple accessors like:
$this->getDB();
$this->getSession();

So even if you change your method of getting to your globals the rest of code won’t care.

I try not to have a bunch of global variables running around because people complain about it too much. :slight_smile:

Instead, I like to create a simple stdClass instance with a single letter variable name and store my variables in there. Once my code has done its’ thing I unset the whole instance.

$c = new stdClass;
$c->one = 'one';
$c->two = 'two';

// work with $c here

unset($c);

There are times though, when I have too many places using a variable for this to be feasible. So I bend a little and use the global variable.