1

Been searching all around but still cannot find a solution for this problem. My problem is that i got these snips of code(Examples):

Core file

class Core {
    public $DB = null;
    public $Handler = null;

    function run() {
        $this->DB = "somedatabase";

        include_once('handler.php');
        $this->Handler = new Handler;

        $this->Handler->run();
    }
}

This is the helper.php example

class Handler extends Core {
    function run() {
        echo "<pre>"; print_r($this); echo "</pre>"; die();
    }
}

Even tho i defined the DB variable before i include the helper then it is still empty inside the helper class. It's defined yes but it's empty. Which means it properly doesn't share the same memory as the Core class.

Keep in mind that the Core class it self is instanced too.

-

Thanks for all suggestions

Edit

PhpMyCoder got it right. Thank you for the detailed and well written reply. For over 2 years i been seeing PHP scopes as being the same or sorta the same as JavaScript's scope. Now i realize that if i extend my "Core" class i get all the methods and properties within it. But the values is private to my class and my class alone.

This is great. Finally i got it.

  • Please post more info into the code. – ThinkingMonkey Dec 29 '11 at 09:49
  • 1
    *(related)* [Learning PHP Class](http://stackoverflow.com/questions/2206387/learning-php-class) – Gordon Dec 29 '11 at 10:00
  • @Gordon - That have nothing to do with this issue or what's so ever. –  Dec 29 '11 at 12:48
  • @ThinkingMonkey - No more code should be needed. How the code works and how it's written is explained in detail. –  Dec 29 '11 at 12:50
  • 1
    @DannieHansen I know, but you seem to have trouble understanding OOP so I felt this introduction might be helpful to you. – Gordon Dec 29 '11 at 13:00
  • @Gorden Thanks but i been using OOP PHP for over 2 years now. Just never been in a situation where a extend doesn't share the same memory as the parent. Updated the post, could you have a look? –  Dec 29 '11 at 13:03
  • 1
    @DannieHansen You seem to have some very basic misconception on how extending a class works. You set `$this->DB = "somedatabase";` in a method of a parent class and then expect to magically show up in another instance of another class (that is a child class). For me the suggestion made sense – edorian Dec 29 '11 at 13:12
  • I don't expect it to magically show up. I expect the handler to extend the current instance and gain the same parent variables / methods as that instance have. Now would you care to explain how that's magical rather than trashing me? –  Dec 29 '11 at 13:51

4 Answers4

9

From what I gather here you are talking about public instance variables. They are performing as OOP would require. Each time you instantiate a class with

$core = new Core();  // or
$handler = new Handler();

Each of them gets a fresh space in memory to store their instance variables. Instance variables are unique to each instance of a class, as the name would suggest. So, two separate instances of Core and Handler do not share instance variables. However since Handler extends Core, two instances of Core are created. One instance is the one that I created on the first line. The other is created so that Handler can extend it on the second line. These two instances of Core are not the same object. To have the same values for Core across all core objects you will need to use static (class) variables.

class Core {
    public static $hello = 'World';
}

var_dump(Core::$hello); //string('Word')

In my example, $hello will always be available to everyone by accessing it with the scope resolution operator, ::. So Handler could access it with either Core::$hello or parent::$hello. If you wanted to only expose this static variable to Core and its subclasses, then you would need to make it protected and access it from within Core with self::$hello and from its subclasses with parent::$hello.

class Core {
    protected static $hello = 'World';

    public function sayHello() {
        echo 'Hello '.self::$hello;  //from within Core, access with `self`
    }
}

class Handler extends Core {
    public function myParentSays() {
        echo 'My parent says: Hello '.parent::$hello;
    }
}

$core = new Core();
$core->sayHello(); // 'Hello World'

$handler = new Handler();
$handler->myParentSays(); // 'My parent says: Hello World'

Check the PHP docs for more on the static keyword and the scope resolution operator.


EDIT
I believe your confusion lies in a misunderstanding of how inheritance works in OOP so let me give you a little real-world-ish example. Let's say you create a class for employees called Employee. This class has a public instance variable (that is, one that can be accessed with ->) for the name of the person. In PHP this would be:

class Employee {
    public $name;

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

Now let's create a new employee:

$tim = new Employee('Tim');

Let's say that we need a new class, Intern, that should subclass Employee. That should be easy enough:

class Intern extends Employee {
    public function makeCoffee(Employee $receiver) {}
}

If we create a new intern now, should his name be Time just because we have already created another employee named Tim? No. That doesn't make sense.

$intern = new Intern();
var_dump($intern->name); //string(0) ""

Now say that setting the name was some complicated and arduous process and we'd rather not have to code it again. With a little modification to our Intern class we can leave the name setting to its superclass, Employee.

class Intern {
    public function __construct($name) {
        parent::__construct($name);
    }

    public function makeCoffee(Employee $receiver) {}
}

Now we can create a new intern and set his or her name. Notice how the other Employee keeps his name.

$intern = new Intern('Something Forgettable');
var_dump($intern->name); // string(21) "Something Forgettable"
var_dump($employee->name); // string(3) "Tim"

Now why is this? In OOP, a subclass/superclass is an "is a" relationship. The Intern "is an" Employee. The Intern has all the same properties and methods as an Employee but because each Intern and Employee are distinct they have their own values for these properties.

With this in mind, I suggest you rethink your strategy for your classes. Does it really make sense that Handler is a Core? Does it make sense that MainController is a Handler?

Bailey Parker
  • 15,599
  • 5
  • 53
  • 91
  • Sweet, i will give it a try here later today and respond. Thanks –  Dec 29 '11 at 10:22
  • Updated the post, could you have a look? Statics did not work. I Guess it's because they only works for the none instanced class? The class it self. –  Dec 29 '11 at 13:04
  • @DannieHansen What pattern are you trying to emulate here? Generally in OOP, superclasses shouldn't need to create (or for that matter, include) their own subclasses. – Bailey Parker Dec 29 '11 at 13:07
  • The thing I'm trying to get together is a handler for controllers and such (CVM). So the handler extends the Core class which then have a init function who set all global variables such as database layer and core configs. Then the handler parse the page for controllers and include needed controllers. These controllers then have a main controller who extends the handler. All other controllers extends their main controller. –  Dec 29 '11 at 13:11
  • My problem is simple. The data i set in Core using my init function doesn't appear in the $this at the handler class. Which may lead to them not sharing same memory? –  Dec 29 '11 at 13:12
  • @DannieHansen I understand where your confusion is. Give me a few minutes to add an explanation to the end of my post. – Bailey Parker Dec 29 '11 at 13:28
  • @DannieHansen Updated. See the edit near the bottom. It's a bit lengthy but I hope it explains everything. – Bailey Parker Dec 29 '11 at 13:50
  • You got the answer for me! Thank you very much for taking the time to write it out clearly. Now i see my idea if extends have been all wrong for the 2 years i been using it :) I wonder how i haven't been stuck as i did now before. Well thank you once more. Appreciate the effort! –  Dec 29 '11 at 14:00
1

Classes don't share memory unless you pass a reference to them. When you make an instance of a class (an object), it is unique. You could have:

$a = new Core();
$b = new Core();
$a->var1 = 'foo';
$b->var1 = 'bar';
echo $a->var1; // 'foo'
echo $b->var1; // 'bar'

The same holds for extending a class. It doesn't explicitly share the values of the fields, it just shares their existence/visibility.

To share the value, you would do something more like this:

$a = new Core();
$b = new Core();
$c = 'foo';
$a->var1 = &$c;
$b->var1 = &$c;
echo $a->var1; // 'foo'
$b->var1 = 'bar';
echo $a->var1; // 'bar'
$c = 'baz';
echo $a->var1; // 'baz'
Grexis
  • 1,502
  • 12
  • 15
1

Variables are only set on objects (class instances). Don't confuse classes with objects.

If you want to have variables bound to classes, use the static keyword:

class Core {
  public static $static = 'abc';
  public $instance = 'xyz';
}
Core::$static = 'x';
$core = new Core();
$core->instance = 'a';
knittl
  • 246,190
  • 53
  • 318
  • 364
0

In PHP, classes are extended, not objects. This is class:

class SomeClass{
   // ...
}

And this is object:

$object = new SomeClass();

So, when your are extending some class, all its protected/public properties are become available to child class.

Timur
  • 6,668
  • 1
  • 28
  • 37