Совместное использование переменных между функциями в PHP без использования глобальных переменных
Вопрос
У меня есть класс для взаимодействия с сервером 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.