2012-05-31 3 views
1

У меня есть класс языка с членами общественными данных:PHP: Как получить доступ к объекту внутри класса

class language { 
    public $error = "There was an error"; 
} 

Тогда у меня есть много различных классов, которые используют этот класс. Как я могу получить доступ к этому классу из других классов? Конечно, вы можете создать экземпляр объекта внутри всех классов, которые его используют, но я полагаю, что это резко снизит производительность, если я буду делать это с несколькими классами.

Мне нужен только один объект, так как я его не меняю. Итак, я сделал

$language = new language(); 

class name { 
    private $language; 

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


    public function method() { 
     mysql_query(...) or die($this->language->error); 
    } 
} 

Это хороший способ сделать это? Теперь мне нужно создать экземпляр в каждом сценарии «мать». И я полагаю, выполняя __construct(), я передаю только подтверждение, так как я не использую слово clone?

ответ

1

мне нужен только один объект

Это шаблон Singleton.

Вот краткий пример способ иметь только один экземпляр вашего класса Язык:

class Language { 
    public $error = "text"; 

    private static $instance = null; 

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

    private function __construct() {} 
} 

$lang = Language::getInstance(); 
$text = $lang->error; 

Вы также можете использовать инъекции зависимостей:

interface ILanguage { 
    public function getError(); 
} 

class Language implements ILanguage { 
    private $error = "error"; 
    public function getError() { 
    return $this->error; 
    } 
} 

class name { 
    private $language; 

    public function __construct(ILanguage $lang) { 
    $this->language = $lang; 
    } 

    public function method() { 
    mysql_query(...) or die($this->language->getError()); 
    } 
} 

$language = new Language(); 
$n = new name($language); 

Этот пример инъекции зависимостей называется constructor injection.

+0

Ага, это обычное известное правило или «шаблон»? $ lang = Язык :: getInstance(); передает ссылку, а не сам объект? –

+0

Это [анти-шаблон] (http://en.wikipedia.org/wiki/Anti-pattern) –

+0

Да, это общий шаблон дизайна: http://en.wikipedia.org/wiki/Singleton_pattern Здесь объект не копируется, потому что, как указано на этой странице: http://php.net/manual/en/language.oop5.references.php 'Когда объект отправляется по аргументу, возвращенному или присвоенному другой переменной, различные переменные а не псевдонимы: они содержат копию идентификатора, которая указывает на тот же объект ». – SirDarius

1

Инстанцировать в Language объект в конструкторе класса:

public function __construct() { 
    $this->language = new Language(); 
} 
+0

Да, но не замедляет ли сценарий и не использует лишнее количество памяти? В любом случае мне не нужно менять то, что находится внутри класса языка. –

+0

Таким образом, он будет создавать отдельный объект для каждого класса, который имеет ошибки или выводит что угодно. –

+1

Если вам нужен «глобальный» объект, вы можете подумать о том, чтобы написать класс 'Language' как [' static'] (http://php.net/manual/en/language.oop5.static.php). – flowfree

1

Если вы не хотите иметь экземпляры этого класса, рассмотреть вопрос о внесении его свойства и методы static:

class language { 
    static public $error = "There was an error"; 
} 

затем использовать их статически:

$error = language::$error; 
+0

Хмм, это интересно. Я не знал, что это сработало. Я думал, что статика - это то, что разделяли объекты. Как вы думаете, лучший метод? Я совершенно новичок в ООП и просто думал о том, что экземпляр объекта больше времени, чем nececcary замедляет сценарий? –

+0

'static' свойства и методы принадлежат самому классу, а не его экземплярам. Они «разделяются» между экземплярами только в том смысле, что они могут получить к ним доступ через псевдокласс «self». Вы получаете статические свойства как 'Class :: $ property' и статические методы как' Class :: method() '. В вашем случае вам понадобится либо [Sintlegon] (http://en.wikipedia.org/wiki/Singleton_pattern), либо класс со статическими свойствами, подобными этому. – lanzz

1

Вместо использования g lobal variable, вы можете передать его через конструктор.

public function __construct($language) { 
    $this->language = $language; 
} 
+0

Да, но я не хочу проходить это время все время. –

2

В основном ваш языковой объект зависит от ваших других объектов. Существует целый ряд факторов, которые необходимо учитывать: - производительность (как разумно создавать экземпляр нового объекта языка каждый раз, когда вам это нужно, или даже это возможно) - тестирование - как вы можете протестировать свои классы, если каждый у вас есть жестко закодированная зависимость от вашего языкового класса - ремонтопригодность/удобочитаемость.

Существуют различные варианты решения проблемы. Тот, который, кажется, больше всего в моде в сообществе PHP, представляет собой контейнер для инъекций зависимостей. Это может быть хорошим решением, если вы находитесь в ситуации с новым полем.

Хорошая статья по общей теме: one by Martin Fowler (кто еще?).

EDIT: Чтобы объяснить немного больше, речь идет о принципе инверсии управления.Я не буду объяснять это подробно, так как не думаю, что я мог бы это сделать, как и Мартин Фаулер среди других, но суть этого в том, что ваши классы не управляют своими собственными зависимостями; это делается в другом месте (отсюда и название Inversion of Control). Существует два разных способа сделать это: инъекция зависимостей (которая может включать или не включать контейнер) и Service Locator. В статье section статьи Мартина Фаулера рассматриваются некоторые различия между ними.

+0

Не могли бы вы кратко объяснить это здесь? –

+0

@StudentofHogwarts Я добавил немного больше объяснений. – liquorvicar

+0

Можете ли вы добавить пример в PHP? –

Смежные вопросы