0

I am interested in Opencart oo programming.

In opencart, from any controller file, we can easily see programming style like this:-

class ControllerAccountAddress extends Controller {
    private $error = array();
    public function index() {
            if (!$this->customer->isLogged()) {
                $this->session->data['redirect'] = $this->url->link('account/address', '', 'SSL');
}

I can see, inside the ControllerAccountAddress class, author can immediately assign properties generated by other class, which at least is not from the extended Controller class or within the same php page. Therefore, I suspect that, some public properties created by other classes were available to be called for usage in this method of "index".

However, when I tried another class like this:-

<?php
class Language{
    public $lang;

    function __construct($the_lang) {
        $this->lang = $the_lang;
    }

    function get_lang(){
        echo $this->lang;   
    }
}
?>

<?php
$try = new Language('English');
$try->get_lang();
?>

Result would be "English".

Then, I attempt to create another class:-

<?php 
class Person {
    public $name;
    function trial() {
        $something = $this->lang . "OK";
    }

}
?>

Then, no matter how I try, the $this->lang cannot be used, and I suspect it has not available to this method.

What can I do so that I can generate properties that are available to be used in other class methods?

user2122657
  • 155
  • 2
  • 10
  • 1
    To access the properties of Language in class person you need to extend it I.e. class Person extends Language – Jay Bhatt Apr 09 '13 at 11:55

2 Answers2

1

$this->lang cannot be used since Person object dosen't have $lang property. What you need is called composition, when one class is composed of other classes. Basicly this means that one object has property that holds another object.

So you want Composition, and you need Dependency Injection to enable this.

For Person to use Language you need this:

class Person {
     public $name;
     public $lang; // This is object!

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

$lang = new Language();
$john = new Person($lang);

Now you can access language like this:

$jonh->lang->method();

This example shows you how to push object through object constructor using Dependency Injection. Just read more about Composition and Dependency Injection.

Hope this helps!

Matija
  • 2,610
  • 1
  • 18
  • 18
0

The class Person has nothing common with Language, so you can't use $lang in it.

But...

You can have a field eg. $mother_language in the class Person like this

class Person {
  public $name;
  public $mother_language;

  function __construct(){ // just to initialize $mother_language
    $this->mother_language = new Language('English');
  }

  function trial() {
    $something = $this->mother_language->lang . "OK";
  }
}
Voitcus
  • 4,463
  • 4
  • 24
  • 40
  • 2
    You should never instantiate a new object inside object consturctor, dependencies should be pushed from outside, so anyone who uses this class knows what is this class dependent on! – Matija Apr 09 '13 at 12:03
  • @Matija could you please take a look at my question? http://stackoverflow.com/questions/15901861/why-not-instantiate-a-new-object-inside-object-constructor – Voitcus Apr 09 '13 at 12:27
  • Yep I did take a look at your question, and I can still tell you that its better to use Dependency Injection then instantiate object in constructor. If you did any unit testing you should know this. When you instantiate dependency in constructor you cant use mock object etc etc... – Matija Apr 09 '13 at 12:45
  • 1
    As of the discussion results of the question I cited, I can agree that the Matija's solution is better. – Voitcus Apr 09 '13 at 19:22