Page 1 of 2

Accessing a variable upward in the scope in an object

Posted: Sat May 31, 2008 8:53 am
by onion2k
If I do something like...

Code: Select all

class Object1 {
  $var = "hello";
  function attach($object) {
    $this->a = $object;
  }
}
 
class Object2 {
  //stuff
}
 
$o = new Object1();
$o->attach(new Object2());
Is there any way that Object2 can get the contents of $var from inside Object1 (eg $o)? Obviously $o can access everything in Object2 through $this->a->whatever. But is it possible to go the other way? I'm attempting to write a system that uses plugins, but I can't figure out a way to let the plugin see the stuff in the object it's plugged into.

Re: Accessing a variable upward in the scope in an object

Posted: Sat May 31, 2008 9:18 am
by arjan.top
Maybe something like this?

Code: Select all

 
class Object1 {
  $var = "hello";
  function attach($object) {
    $this->a = $object;
    $this->a->parent($this);
  }
}
 

Re: Accessing a variable upward in the scope in an object

Posted: Sat May 31, 2008 9:47 am
by Benjamin
Yeah this tested out ok..

Code: Select all

 
class parent_class
{
    private $_child;
    
    public $var_test;
 
    public function __construct()
    {
        $this->_set_a_var();
    }
    
    public function attach($child)
    {
        $this->_child = $child;
    }
    
    private function _set_a_var()
    {
        $this->var_test = 'I am the parent!';
    }
}
 
class child_class
{
    public function __construct($parent)
    {
        $this->_parent = $parent;
        $this->_echo_parent_var();
    }
    
    private function _echo_parent_var()
    {
        echo "I'm talking for my mom and she said: {$this->_parent->var_test}<br />";
    }
}
 
$parent = new parent_class();
$parent->attach(new child_class($parent));
 

Re: Accessing a variable upward in the scope in an object

Posted: Sat May 31, 2008 10:28 am
by Mordred
"child/parent" is a metaphor normally used with class inheritance. "attach/owner" sounds better.

Re: Accessing a variable upward in the scope in an object

Posted: Sat May 31, 2008 10:31 am
by Benjamin
Mordred wrote:"child/parent" is a metaphor normally used with class inheritance. "attach/owner" sounds better.
Yeah I'm not really worried about it. I am more concerned with giving onion2k a solution that is acceptable to him.

Re: Accessing a variable upward in the scope in an object

Posted: Sat May 31, 2008 11:16 am
by onion2k
Well, Astions approach works, so thanks, and it's inspired me to use a slightly modified idea. Rather than passing a reference to the owner object in the call I'm enforcing a 'registerOwner' function in the interface.. eg..

Code: Select all

class Object1 {
  function attach($object) {
    $this->plugin = $object;
    $this->plugin->registerOwner($this);
  }
}
 
class Object2 {
  function registerOwner($owner) {
    $this->_owner = $owner;
  }
}
That means Object2 can access everything necessary from Object1, and it saves having to pass the owner object to the plugin when it's initialised. That feels a bit tidier to me.

Cheers for the help everyone.

Re: Accessing a variable upward in the scope in an object

Posted: Sat May 31, 2008 9:59 pm
by Chris Corbyn
Looks good to me :) The alternative is to pass $this to each method which needs it.

Re: Accessing a variable upward in the scope in an object

Posted: Sat May 31, 2008 10:38 pm
by Benjamin
Yeah either way. You just need to get an instance of it over the other class somehow. In my framework I use a kernel that in addition to a number of other things, holds an object of every class. So I can call any method of any class from any place and it saves a ton of memory PLUS it's very quick.

I can do something like:

Code: Select all

 
class foo
{
    public function __construct()
    {
        $this->kernel = kernel::get_instance();
    }
 
    public function blah()
    {
        # just for clarification: get_page(database query, current page, results per page)
        # returns an array containing records for page 1 or false on failure
        if (false === ($records = $this->kernel->pagination->get_page("select a, b, c, d from users where active = '1'", 1, 50)))
        {
            # we set a status message
            $this->kernel->status->error("There was an error processing your request.");
            
            # this query shouldn't have failed so log this
            $this->kernel->system_log->add_entry(get($class), __FILE__, __LINE__, "unexpected database query failure", 'E_USER_ERROR');
            return false;
        }
        
        return $records;
    }
}
 
I really enjoy coding like this. I don't want to reveal too much yet, but I feel like I can do about 10 times more with half the code using 25% the resources. I'm going to make this open source when I feel it's ready.

Re: Accessing a variable upward in the scope in an object

Posted: Sat May 31, 2008 10:56 pm
by Christopher
If you have dependencies like this, you might want to ask what you actually need done:

Code: Select all

class Object1 {
  function attach($object) {
    $this->plugin = $object;
  }
  function doSomething() {
    $this->whatIWant = $this->plugin->something($this->whatObject2Needs);
  }
}

Re: Accessing a variable upward in the scope in an object

Posted: Sat May 31, 2008 11:47 pm
by Mordred
astions wrote:Yeah either way. You just need to get an instance of it over the other class somehow. In my framework I use a kernel that in addition to a number of other things, holds an object of every class. So I can call any method of any class from any place and it saves a ton of memory PLUS it's very quick.
So, basically you've invented global functions with lots of -> thrown in.

I'm all for the global functions to access "kernel" functionality, but I hate typing useless syntax sugar around, just because PHP doesn't have any reasonable scope modifiers (and no, 'global' is not reasonable).

For example instead of $this->kernel->db->query("blah") I do DBQuery("blah"), you do the math on how much typing it saves and how much readability it adds. I do have a DB object that I can pass around should I ever want to use two DB connections simultaneously, but I've yet to come to this need. Instead, with this wrapper of the "default" db connection, I cover 99.999% of use cases with significantly less typing and maintenance code. I would not bear to type a hundred -> which will always have the same object on the left.

Re: Accessing a variable upward in the scope in an object

Posted: Sat May 31, 2008 11:56 pm
by Benjamin

Re: Accessing a variable upward in the scope in an object

Posted: Sun Jun 01, 2008 3:17 pm
by onion2k
Well, it's not ready for public beta yet.. but this is the how the code works in practise now...

Code: Select all

$image =& new Image(IMAGE_BASE.DIRECTORY_SEPARATOR."drops.jpg");
$image->attach(new image_fx_resize(100,100));
header("Content-type: image/jpg");
$image->imageJpeg();
That opens a jpeg image, resizes it to 100*100 pixels, and outputs it to the browser. You can add as many attachments as you like.

It's pretty sweet. All delightful TDD unit tested loveliness too. Some way to go yet mind you.

Re: Accessing a variable upward in the scope in an object

Posted: Sun Jun 01, 2008 3:31 pm
by Benjamin
Looks good. I would try to write so that I wouldn't have to pass the "IMAGE_BASE.DIRECTORY_SEPARATOR." in the image path argument. Not sure if that would fit in your coding style or not.

Re: Accessing a variable upward in the scope in an object

Posted: Sun Jun 01, 2008 3:37 pm
by onion2k
astions wrote:Looks good. I would try to write so that I wouldn't have to pass the "IMAGE_BASE.DIRECTORY_SEPARATOR." in the image path argument. Not sure if that would fit in your coding style or not.
That's just the way I write filename paths. If the image was in the same directory as the script then "drops.jpg" would work fine. $_FILES['upload']['tmp_name'] also works.

Re: Accessing a variable upward in the scope in an object

Posted: Sun Jun 01, 2008 3:42 pm
by VladSun
Myabe I'm wrong, but I feel this topic is related to one of mine: viewtopic.php?f=19&t=72764&hilit=owner