【问题标题】:How to make a globally accessible object如何制作全局可访问的对象
【发布时间】:2009-08-30 09:55:30
【问题描述】:

您好,我有一些类的集合,其中一些应该是全局可访问的。

我在 Zend_Registry 中发现了类似的东西,但是阅读它的代码我无法理解对静态函数的调用如何返回一个类的初始化实例...

我需要做一些类似的事情:

<?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();
?>

在这里我已经过滤了 Request 对象,我希望控制器能够访问已经过滤的请求。

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

?>

我不知道如何实现那个Application::getResource(),我唯一知道的是它必须是一个静态方法,因为它不能与特定的实例相关。

【问题讨论】:

  • 对不起,我不明白这个问题。你想用 Application::getResource() 做什么?你的代码有什么问题?
  • 您应该尽可能避免使用全局变量。一个更好的选择是依赖注入/控制反转——你应该查一下。
  • 我认为在 PHP 中避免使用全局变量是没有意义的。脚本往往非常小,以至于实现/执行此类模式的开销将花费您更多的开发人员时间/服务器时间。

标签: php oop global-variables


【解决方案1】:

除了静态方法之外,PHP 还具有静态属性:类的本地属性。这可以用来实现单例,或者实际上是一个注册表:

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];
    }
}

【讨论】:

    【解决方案2】:

    1:您可以使用global 关键字访问全局变量:

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

    2:您可以使用$GLOBALS super-global:

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

    3:您可以定义一个singleton class(维基百科也有一个nice example)。

    4:您可以将全局变量作为公共静态成员(或具有公共 getter/setter 的私有静态成员)添加到类中:

    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);
    

    我不推荐前两种方法,无意中覆盖这些全局变量的值太容易了。

    【讨论】:

    • 还有$GLOBALS,它基本上是global的替代语法。
    【解决方案3】:

    在我看来,您可能需要某种形式的单例设计模式;

    检查this

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-23
      • 1970-01-01
      • 2016-05-09
      • 2013-05-30
      • 2012-04-11
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多