简体   繁体   中英

PHP: How to access object inside class

I have a language class with public data members:

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

Then I have many different classes that uses this class. How can I access this class from within other classes? You could of course instantiate an object of it inside all the classes that uses it, but I suppose that would drastically decrease the performance, if I were to do that with multiple classes.

I do only need one object, since I don't change them anyway. So, I've done

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

Is this a good way to do it? Now I have to instantiate it in every "mother" script. And I suppose by doing __construct() I'm only passing a refrence, since I don't use the clone word?

Basically your language object is a dependency of your other objects. There are a number of factors you need to consider: - performance (how wise it is to instantiate a new language object each time you need it, or whether that is even possible) - testing - how you could test your classes if each one has a hard-coded dependency on your language class - maintainability/readability.

There are various different solutions to the problem. The one that seems to be most in fashion in the PHP community is the Dependency Injection Container. This can be a good solution if you are in a greenfield situation.

A good article on the general subject is one by Martin Fowler (who else?).

EDIT: To explain a bit more the article deals with the Inversion of Control principle. I won't explain it in depth as I don't think I could do it as well as Martin Fowler amongst others but the nub of it is that your classes do not manage their own dependencies; that is done elsewhere (hence the name Inversion of Control). There are broadly two different ways of doing it - Dependency Injection (which may or may not involve a Container) and Service Locator. This section of Martin Fowler's article deals with some of the differences between the two.

Instantiate the Language object in the constructor of your class:

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

If you do not want to have instances of this class, consider making its properties and methods static :

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

then use them statically:

$error = language::$error;

Instead of using global variable, you could pass it via constructor.

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

I do only need one object

This is the Singleton pattern.

Here is a quick example of a way to have only one instance of your Language class:

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;

You can also use dependency injection:

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

This example of dependency injection is called constructor injection .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM