2

Hi i have a little collection of classes some of which should be globally accessible.

I found something similar in Zend_Registry, but reading its code i cant understand how a call to a static function could return an initialized instance of a class...

i need to do something like:

<?php
//index.php
$obj = new myUsefulObject();
$obj->loadCfg("myFile.xml");
$req = new HTTPRequest();
$req->filter("blablabla");
myappp::registerClass("object",$obj);
myappp::registerClass("request",$req);
$c = new Controller();
$c->execute();
?>

Here i have filtered the Request object and i want the controller to be able to reach that already filtered request.

<?php
class Controller
{
    function __construct()
    {
        $this->request = Application::getResource("request");//This must be the filtered var =(
    }
}

?>

I don't know how to implement that Application::getResource(), the only thing i know is that it must be a static method because it can't be related to a specific instance.

fat
  • 5,098
  • 4
  • 28
  • 31
  • 1
    Sorry but i don't understand the question. What do you want to do with Application::getResource()? What is the problem with your code? – mck89 Aug 30 '09 at 10:12
  • 1
    You should avoid globals where possible. A much better option is dependency injection/inversion of control - you should look it up. – Jani Hartikainen Aug 30 '09 at 10:35
  • I don't think that it makes sense to avoid globals in PHP. Scripts tend to be so small that the overhead for implementing/executing such patterns will cost you much more developer time/server time than necessary. – soulmerge Aug 31 '09 at 07:28

3 Answers3

3

Aside from static methods, PHP also has static properties: properties that are local to the class. This can be used to implement singletons, or indeed a Registry:

class Registry { 
    private static $_registry;

    public static function registerResource($key, $object) 
    { 
        self::$_registry[$key] = $object; 
    }

    public static function getResource($key) { 
        if(!isset(self::$_registry[$key]))
            throw InvalidArgumentException("Key $key is not available in the registry");

        return self::$_registry[$key];
    }
}
gnarf
  • 105,192
  • 25
  • 127
  • 161
NSSec
  • 4,431
  • 1
  • 27
  • 29
1

1: You can acess global variables with the global keyword:

$myVar = new SomethingProvider();
class MyClass {
    public function __construct() {
        global $myVar;
        $myVar->doSomething();
    }
}

2: You can do the same using the $GLOBALS super-global:

$myVar = new SomethingProvider();
class MyClass {
    public function __construct() {
        $GLOBALS['myVar']->doSomething();
    }
}

3: You can define a singleton class (the wikipedia has a nice example, too).

4: You could add globals as public static members (or private static members with public getters/setters) to a class:

class Constants {
    const NUM_RETIES = 3;
}
if ($tries > Constants::NUM_RETRIES) {
    # User failed password check too often.
}

class Globals {
    public static $currentUser;
}
Globals::$currentUser = new User($userId);

I wouldn't recommend the first two methods, overwriting the values of these global variables unintentionally is too easy.

soulmerge
  • 73,842
  • 19
  • 118
  • 155
0

Seems to me like you might need some form of Singleton design pattern;

Check this out!

Hope it helps!

Kris
  • 2,100
  • 5
  • 31
  • 50