Совместное использование переменных между функциями в PHP без использования глобальных переменных

StackOverflow https://stackoverflow.com/questions/550753

  •  23-08-2019
  •  | 
  •  

Вопрос

У меня есть класс для взаимодействия с сервером memcache.У меня есть разные функции для вставки, удаления и извлечения данных.Первоначально каждая функция вызывала memcache_connect(), однако в этом не было необходимости, например:

mc->insert()  
mc->get()  
mc->delete() 

создало бы три подключения к memcache.Я обошел это, создав конструкцию для класса:

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

и затем, используя $this->mem везде, где был необходим ресурс, поэтому каждая из трех функций использует одно и то же memcache_connect ресурс.

Это нормально, однако, если я вызываю класс внутри других классов, например:

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

тогда это все еще делает два memcache_connect звонит, когда это только потребности один.

Я могу сделать это с глобальными файлами, но я бы предпочел не использовать их, если в этом нет необходимости.

Пример глобальной реализации:

$resource = memcache_connect( ... );

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

}

Тогда независимо от того, сколько раз вызывается класс, будет только один вызов memcache_connect.

Есть ли способ сделать это или я должен просто использовать глобальные переменные?

Это было полезно?

Решение

Я бы закодировал другой класс, используя шаблон 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, ...)
...

Другие советы

Передать в экземпляре 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);

и т.д.

Я думаю, вы ищете здесь статические свойства.

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.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top