Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中的函数之间共享变量而不使用全局变量_Php_Oop_Global - Fatal编程技术网

在PHP中的函数之间共享变量而不使用全局变量

在PHP中的函数之间共享变量而不使用全局变量,php,oop,global,Php,Oop,Global,我有一个与memcache服务器交互的类。我有不同的插入、删除和检索数据的功能。最初,每个函数都调用了memcache\u connect(),但这是不必要的,例如: mc->insert() mc->get() mc->delete() 将建立三个memcache连接。我通过为类创建一个构造来解决这个问题: function __construct() { $this->mem = memcache_connect( ... ); } 然后在需要资

我有一个与memcache服务器交互的类。我有不同的插入、删除和检索数据的功能。最初,每个函数都调用了
memcache\u connect()
,但这是不必要的,例如:

mc->insert()  
mc->get()  
mc->delete() 
将建立三个memcache连接。我通过为类创建一个构造来解决这个问题:

function __construct() {
    $this->mem = memcache_connect( ... );
}
然后在需要资源的地方使用
$this->mem
,这样三个函数中的每一个都使用相同的
memcache\u connect
资源

这没关系,但是如果我在其他类中调用该类,例如:

class abc
{
    function __construct() {
        $this->mc = new cache_class;
    }
}    
class def
{
    function __construct() {
        $this->mc = new cache_class;
    }
}
然后它仍在进行两次
memcache\u connect
调用,而它只需要一次

我可以用globals来做这件事,但如果不需要的话,我宁愿不使用globals

全局实现示例:

$resource = memcache_connect( ... );

class cache_class
{
    function insert() {
        global $resource;
        memcache_set( $resource , ... );
    }
    function get() {
        global $resource;
        return memcache_get( $resource , ... );
    }

}
然后,无论调用该类多少次,都只会调用一次
memcache\u connect


有没有办法做到这一点,或者我应该只使用globals?

在MC实例中传递:

class abc
{
    function __construct($mc) {
        $this->mc = $mc;
    }
}    
class def
{
    function __construct($mc) {
        $this->mc = $mc;
    }
}

$mc = new cache_class;
$abc = new abc($mc);

等等。

我将使用singleton模式编写另一个类,以获取memcache的唯一实例。像这样-

class MemCache 
{ 
  private static $instance = false;   
  private function __construct() {}

  public static function getInstance()
  { 
    if(self::$instance === false)
    { 
      self::$instance = memcache_connect(); 
    } 

    return self::$instance; 
  } 
}
用法-

$mc = MemCache::getInstance();
memcache_get($mc, ...)
...

我想你在这里寻找的是静态属性

class mc {
    private static $instance;

    public static function getInstance() {
        if (self::$instance== null) {
            self::$instance= new self;
        }
        return self::$instance;
    }

    private function __construct() {
        $this->mem = memcache_connect(...);
    }
}

这实现了一个基本的单例模式。而不是构造对象调用
mc::getInstance()
。看看。

您应该使用依赖项注入。单例模式和静态构造被认为是不好的做法,因为它们本质上是全局的(并且有很好的理由——它们将您固定为使用您实例化的任何类,而不是其他类)

下面是一些您应该做的事情,以便于维护

class MemCache {
    protected $memcache;

    public function __construct(){
        $this->memcache = memcache_connect();
    }
}

class Client {
    protected $MemCache;

    public function __construct( MemCache $MemCache ){
        $this->MemCache = $MemCache;
    }

    public function getMemCache(){
        return $this->MemCache;
    }
}

$MemCache = new MemCache();
$Client = new Client($MemCache);
$MemCache1 = $Client->getMemCache();

// $MemCache and $MemCache1 are the same object. 
// memcache_connect() has not been called more than once.

这是一个合理的解决方案,但让我们面对现实,这是一个全球性的问题。:)这就是我要做的。你不能测试它,但老实说,谁来测试这类东西?问题是如果一小部分不可测试,那么整个代码的其余部分如何保持可测试性。或者你将如何为其他测试实现一个模拟的MemCache对象?@cletus:它使用一个全局模式,但它不使用全局范围。程序在环境中运行;在这种组织级别上,所有内容都是全局的,即使您的所有真实数据都在类属性中。你想避免在全局中使用变量,但是外部数据源的接口必须位于某个地方,而且你希望这些变量都是单例的。有趣的是,人们在只阅读了答案的第一句话之后就投了反对票+再一次。