Accessing a variable upward in the scope in an object

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Accessing a variable upward in the scope in an object

Post 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.
User avatar
arjan.top
Forum Contributor
Posts: 305
Joined: Sun Oct 14, 2007 4:36 am
Location: Hoče, Slovenia

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

Post by arjan.top »

Maybe something like this?

Code: Select all

 
class Object1 {
  $var = "hello";
  function attach($object) {
    $this->a = $object;
    $this->a->parent($this);
  }
}
 
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

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

Post 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));
 
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

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

Post by Mordred »

"child/parent" is a metaphor normally used with class inheritance. "attach/owner" sounds better.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

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

Post 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.
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

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

Post 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.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

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

Post by Chris Corbyn »

Looks good to me :) The alternative is to pass $this to each method which needs it.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

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

Post 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.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

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

Post 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);
  }
}
(#10850)
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

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

Post 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.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

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

Post by Benjamin »

User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

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

Post 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.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

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

Post 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.
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

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

Post 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.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

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

Post 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
There are 10 types of people in this world, those who understand binary and those who don't
Post Reply